简体   繁体   English

Django Rest Framework - 如何在 ModelSerializer 中添加自定义字段

[英]Django Rest Framework - How to add custom field in ModelSerializer

I created a ModelSerializer and want to add a custom field which is not part of my model.我创建了一个ModelSerializer并想添加一个不属于我的模型的自定义字段。

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.当我添加这个字段并调用我的validate()函数时,这个字段不是attr字典的一部分。 attr contains all model fields specified except the extra fields. attr包含指定的所有模型字段,但额外字段除外。 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.然后我得到一个错误,因为customField不是我的模型的一部分 - 什么是正确的,因为我只想为这个序列化程序添加它。

Is there any way to add a custom field?有没有办法添加自定义字段?

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.您可以使用SerializerMethodField ,它允许您将任何方法插入序列化程序。

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

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

You're doing the right thing, except that CharField (and the other typed fields) are for writable fields.您正在做正确的事情,除了CharField (和其他类型字段)用于可写字段。

In this case you just want a simple read-only field, so instead just use:在这种情况下,您只需要一个简单的只读字段,因此只需使用:

customField = Field(source='get_absolute_url')

...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')

ps Since the custom field isn't really a field in your model, you'll usually want to make it read-only, like so: ps 由于自定义字段实际上并不是模型中的字段,因此您通常希望将其设为只读,如下所示:

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

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来源: https : //stackoverflow.com/a/18396622/3220916

To show self.author.full_name , I got an error with Field .为了显示self.author.full_name ,我收到了Field错误。 It worked with ReadOnlyField :它与ReadOnlyField一起使用:

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

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.使用最新版本的 Django Rest Framework,您需要在模型中使用要添加的字段的名称创建一个方法。

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

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

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

After reading all the answers here my conclusion is that it is impossible to do this cleanly.在阅读了这里的所有答案后,我的结论是不可能干净利落地做到这一点。 You have to play dirty and do something hadkish like creating a write_only field and then override the validate and to_representation methods.你必须玩得很脏,做一些像创建一个 write_only 字段,然后覆盖validateto_representation方法之类的to_representation This is what worked for me:这对我有用:

class FooSerializer(ModelSerializer):

    foo = CharField(write_only=True)

    class Meta:
        model = Foo
        fields = ["foo", ...]

    def validate(self, data):
        foo = data.pop("foo", None)
        # Do what you want with your value
        return super().validate(data)

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data["foo"] = whatever_you_want
        return data

I was looking for a solution for adding a writable custom field to a model serializer.我正在寻找一种将可写自定义字段添加到模型序列化程序的解决方案。 I found this one, which has not been covered in the answers to this question.我找到了这个,这个问题的答案中没有涉及到。

It seems like you do indeed need to write your own simple Serializer.看起来您确实需要编写自己的简单序列化程序。

class PassThroughSerializer(serializers.Field):
    def to_representation(self, instance):
        # This function is for the direction: Instance -> Dict
        # If you only need this, use a ReadOnlyField, or SerializerField
        return None

    def to_internal_value(self, data):
        # This function is for the direction: Dict -> Instance
        # Here you can manipulate the data if you need to.
        return data

Now you can use this Serializer to add custom fields to a ModelSerializer现在您可以使用此 Serializer 将自定义字段添加到 ModelSerializer

class MyModelSerializer(serializers.ModelSerializer)
    my_custom_field = PassThroughSerializer()

    def create(self, validated_data):
        # now the key 'my_custom_field' is available in validated_data
        ...
        return instance

This also works, if the Model MyModel actually has a property called my_custom_field but you want to ignore its validators.如果 Model MyModel实际上有一个名为my_custom_field的属性但您想忽略它的验证器,这也有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Django Rest Framework:将ModelSerializer作为ModelSerializer中的字段不显示选择 - Django Rest Framework: ModelSerializer as field in a ModelSerializer doesn't show choices Django REST Framework - ModelSerializer 中的附加字段 - Django REST Framework - Additional field in ModelSerializer Django rest框架ModelSerializer - Django rest framework ModelSerializer 如何在Django REST中将字符串添加到ModelSerializer - How to add string to a ModelSerializer in Django REST Django Rest Framework ModelSerializer自定义序列化器字段to_internal_value不会保存到对象 - Django Rest Framework ModelSerializer custom serializer field to_internal_value doesn't save to object Django Rest Framework在使用ModelSerializer保存到视图集中之前向模型添加字段 - Django Rest Framework add field to model before saving in viewset using ModelSerializer 在 Django Rest Framework ModelSerializer 中指定自定义嵌套对象 - Specifying custom nested objects in Django Rest Framework ModelSerializer 如何在 Django REST Framework ModelSerializer 的创建函数中使用 field.set()? - How to use field.set() in create function for Django REST Framework ModelSerializer? django rest框架嵌套的modelserializer - django rest framework nested modelserializer Django Rest Framework:如何在GET请求的响应中添加自定义字段? - Django Rest Framework : How to add a custom field to the response of the GET request?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM