[英]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 字段,然后覆盖validate
和to_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.