Django Rest Framework - How to add custom field in

2019-01-16 17:50发布

问题:

I created a ModelSerializer and want to add a custom field which is not part of my model.

I found a description to add extra fields here and I tried the following:

customField = CharField(source='my_field')

When I add this field and call my validate() function then this field is not part of the attr dict. attr contains all model fields specified except the extra fields. So I cannot access this field in my overwritten validation, can I?

When I add this field to the field list like this:

class Meta:
    model = Account
    fields = ('myfield1', 'myfield2', 'customField')

then I get an error because customField is not part of my model - what is correct because I want to add it just for this serializer.

Is there any way to add a custom field?

回答1:

You're doing the right thing, except that CharField (and the other typed fields) are for writable fields.

In this case you just want a simple read-only field, so instead just use:

customField = Field(source='get_absolute_url')


回答2:

In fact there a solution without touching at all the model. You can use SerializerMethodField which allow you to plug any method to your serializer.

class FooSerializer(ModelSerializer):
    foo = serializers.SerializerMethodField()

    def get_foo(self, obj):
        return "Foo id: %i" % obj.pk


回答3:

here answer for your question. you should add to your model Account:

@property
def my_field(self):
    return None

now you can use:

customField = CharField(source='my_field')

source: https://stackoverflow.com/a/18396622/3220916



回答4:

...for clarity, if you have a Model Method defined in the following way:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

You can add the result of calling said method to your serializer like so:

class MyModelSerializer(serializers.ModelSerializer):
    model_method_field = serializers.CharField(source='model_method')

p.s. Since the custom field isn't really a field in your model, you'll usually want to make it read-only, like so:

class Meta:
    model = MyModel
    read_only_fields = (
        'model_method_field',
        )


回答5:

With the last version of Django Rest Framework, you need to create a method in your model with the name of the field you want to add.

class Foo(models.Model):
    . . .
    def foo(self):
        return 'stuff'
    . . .

class FooSerializer(ModelSerializer):
    foo = serializers.ReadOnlyField()

    class Meta:
        model = Foo
        fields = ('foo',)


回答6:

To show self.author.full_name, I got an error with Field. It worked with ReadOnlyField:

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    author_name = ReadOnlyField(source="author.full_name")
    class Meta:
        model = Comment
        fields = ('url', 'content', 'author_name', 'author')