ModelSerializer使用模型属性

San*_*its 80 django-rest-framework

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

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])
Run Code Online (Sandbox Code Playgroud)

serializers.py:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Run Code Online (Sandbox Code Playgroud)

当试图访问相关的URL时,我在ext_link属性上遇到了序列化程序异常(KeyError).

我如何序列化ext_link属性?

Tom*_*tie 117

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

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

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Run Code Online (Sandbox Code Playgroud)

编辑:在REST框架3中添加__CODE__将只是工作 - 不需要显式添加字段.

  • 我使用的是3.3.x,只是在字段中添加属性是不够的.我仍然需要通过ext_link = serializers.ReadOnlyField()显式添加. (12认同)
  • 注意:使用`fields ="__ all __"`我还必须使用版本3.7.7将`myfield = serializers.ReadOnlyField()`添加为指定的jarmod (7认同)
  • 在Python 3.5.1和Django 1.10上使用DRF 3.4.6,添加到字段工作正常. (4认同)
  • ***一个注意事项***:Meta中的字段列表是可选的.如果省略`fields`,在上面的例子中,你将获得序列化数据中的所有`MyModel`字段和`ext_link`.这对于复杂的模型来说真的很棒!*编辑*:至少,这对于`djangorestframework == 2.3.14`是正确的. (3认同)
  • 对我来说,使用serializers.Field 给出了一个错误。如果未定义 to_representation 并且视图是只读的,“serializers.ReadOnlyField”确实可以工作。 (2认同)

Wil*_*low 13

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

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

因此,对于这个例子,我会这样做:

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

    class Meta:
        model = MyModel
        fields = ('name', 'ext_link')
Run Code Online (Sandbox Code Playgroud)

我已经能够用ListFieldDictField、 和IntegerField来做到这一点。


suh*_*lvs 6

作为@Robert Townley评论,此版本适用3.8.2

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

    class Meta:
        model = MyModel
        fields = "__all__"
Run Code Online (Sandbox Code Playgroud)