django 如何在ModelSerializer中添加自定义字段?

8e2ybdfx  于 2023-05-19  发布在  Go
关注(0)|答案(8)|浏览(182)

我创建了一个ModelSerializer,并希望添加一个不属于我模型的自定义字段。
我在这里找到了添加额外字段的说明,并尝试了以下操作:

customField = CharField(source='my_field')

当我添加这个字段并调用我的validate()函数时,这个字段不是attr dict的一部分。attr包含指定的所有模型字段,除了额外字段。所以我无法在我的覆盖验证中访问此字段,是吗?
当我像这样将此字段添加到字段列表时:

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

然后我得到一个错误,因为customField不是我的模型的一部分--什么是正确的,因为我只想为这个序列化器添加它。
有没有办法添加自定义字段?

np8igboo

np8igboo1#

事实上,有一个解决方案,而不触及所有的模型。您可以使用SerializerMethodField,它允许您将任何方法插入序列化程序。

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

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

qvk1mo1f2#

这样做是正确的,除了CharField(和其他类型字段)是用于可写字段。
在这种情况下,您只需要一个简单的只读字段,因此只需用途:

customField = Field(source='get_absolute_url')
vom3gejh

vom3gejh3#

...为清楚起见,如果您以以下方式定义了模型方法:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

你可以像这样将调用上述方法的结果添加到序列化器中:

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

p.s.由于自定义字段在你的模型中并不是一个真正的字段,你通常会想让它只读,就像这样:

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

70gysomp4#

阅读完这里所有的答案,我的结论是,不可能干净地做到这一点。你必须玩一些肮脏的游戏,比如创建一个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
htrmnn0y

htrmnn0y5#

这里回答你问题。您应该将以下内容添加到您的模型帐户:

@property
def my_field(self):
    return None

现在您可以用途:

customField = CharField(source='my_field')

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

wribegjk

wribegjk6#

为了显示self.author.full_name,我得到了一个错误FieldReadOnlyField

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

vs3odd8k7#

我正在寻找一种解决方案,用于向模型序列化程序添加可写的自定义字段。我找到了这个,这个问题的答案中没有包括。
看起来您确实需要编写自己的简单串行化程序。

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

现在可以使用此序列化程序向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

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

kh212irz

kh212irz8#

在Django Rest Framework的最新版本中,您需要在模型中创建一个方法,该方法具有您想要添加的字段的名称。

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

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

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

相关问题