如何使用ModelSerializer序列化模型@property?

问题描述 投票:0回答:4

我正在尝试序列化包含我也想序列化的属性字段的模型。

models.py:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    slug = models.AutoSlugField(populate_from='name')

    @property
    def ext_link(self):
        return "/".join([settings.EXT_BASE_URL, self.slug])

序列化器.py:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')

尝试访问相关 URL 时,我在

ext_link
属性上收到序列化程序异常 (KeyError)。

如何序列化

ext_link
属性?

django-models django-rest-framework django-serializer
4个回答
177
投票

因为它不是模型字段,所以需要显式添加到序列化器类中

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.Field()

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')

56
投票

作为

@Robert Townley
的评论,此版本适用于
3.8.2
:

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.ReadOnlyField()

    class Meta:
        model = MyModel
        fields = "__all__"

12
投票

接受的答案似乎对我不起作用,

ReadOnlyField
也不起作用。

但是,当我使用与属性函数的返回类型相对应的字段时,我取得了成功。

举个例子,我会这样做:

class MyModelSerializer(serializers.ModelSerializer):
    ext_link = serializers.CharField()

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')

我也可以使用

ListField
DictField
IntegerField
来完成此操作。


0
投票

您可能想要做的另一件事是添加一个属性,其内容不是字符串。假设您有一个名为 Person 的模型和另一个名为 Food 的模型,如下所示(我们假设每种食物只有一个人最喜欢,从而使其成为

OneToMany
连接):

class Person(models.Model):
    name = models.CharField(max_length=255)

    @property
    def favorite_foods(self):
        return Food.objects.filter(person=self.pk)

class Food(models.Model):
    name = models.CharField(max_length=255)
    persons_favorite = models.ForeignKey(Person, on_delete=models.CASCADE)

如果你想在

favorite_foods
的序列化器中添加
Person
,你所要做的就是:

class PersonSerializer(serializers.ModelSerializer):
    favorite_foods = FoodSerializer(read_only=True, many=True)

    class Meta:
        model = Person
        fields = ('name', 'favorite_foods')
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.