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

我创建了一个 ModelSerializer,并希望添加一个自定义字段,这不是我的模型的一部分。

我找到了一个添加额外字段 给你的描述,并尝试了以下操作:

customField = CharField(source='my_field')

当我添加这个字段并调用我的 validate()函数时,这个字段不是 attr结构的一部分。attr包含除额外字段外指定的所有模型字段。所以我不能在覆盖验证中访问这个字段,是吗?

将此字段添加到字段列表时,如下所示:

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

然后我得到一个错误,因为 customField不是我的模型的一部分-什么是正确的,因为我想添加它只是为了这个序列化程序。

有什么方法可以添加自定义字段吗?

114203 次浏览

除了 CharField(和其他类型化字段)用于可写字段之外,您做的是正确的。

在这种情况下,您只需要一个简单的只读字段,因此只需使用:

customField = Field(source='get_absolute_url')

这里回答你的问题。 你应加入你的模型帐户:

@property
def my_field(self):
return None

现在你可以使用:

customField = CharField(source='my_field')

来源: https://stackoverflow.com/a/18396622/3220916

... 为了清楚起见,如果你有一个模型方法定义如下:

class MyModel(models.Model):
...


def model_method(self):
return "some_calculated_result"

您可以像下面这样将调用该方法的结果添加到序列化程序:

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

附言。由于自定义字段实际上不是模型中的字段,所以通常需要将其设置为只读,如下所示:

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

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

为了显示 self.author.full_name,我在使用 Field时遇到了一个错误:

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

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

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.

看起来您确实需要编写自己的简单序列化程序。

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

现在可以使用此 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

如果 ModelMyModel实际上有一个名为 my_custom_field的属性,但是您想要忽略它的验证器,那么这也可以工作。

在阅读了这里的所有答案之后,我的结论是不可能干净利落地做到这一点。您必须使用下流的方法,并执行一些新奇的操作,比如创建一个 write _ only 字段,然后覆盖 validateto_representation方法。这就是对我有效的方法:

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