首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django Rest框架,如何在ModelSerializer中包含“ModelSerializer”字段和相关字段?

Django Rest框架,如何在ModelSerializer中包含“ModelSerializer”字段和相关字段?
EN

Stack Overflow用户
提问于 2016-07-07 12:24:49
回答 8查看 59.2K关注 0票数 73

我有两个模型,一个有M2M关系和一个相关的名称。我希望在序列化程序和相关字段中包括所有字段。

models.py:

代码语言:javascript
运行
复制
class Pizza(models.Model):
    name = models.CharField(max_length=50, unique=True)
    toppings = models.ManyToManyField(Topping, null=True, blank=True, related_name='pizzas')

class Topping(models.Model):
    name = models.CharField(max_length=50, unique=True)
    price = models.IntegerField(default=0)

serializer.py:

代码语言:javascript
运行
复制
class ToppingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Topping
        fields = '__all__' 

这是可行的,但它不包括相关的领域。

代码语言:javascript
运行
复制
 fields = ['name', 'price', 'pizzas'] 

这和我想要的完全一样,但是当Toppings模型有很多字段时会发生什么。我想做这样的事情:

代码语言:javascript
运行
复制
fields = ['__all__', 'pizzas']

此语法将导致错误,说明如下:

字段名__all__对模型无效

有没有办法达到通缉的行为?或者在使用相关名称时必须手动键入字段?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2016-11-01 15:42:44

我刚刚检查了Django Rest Framework的源代码。您想要的行为在框架中似乎不受支持。

fields选项必须是一个列表、一个元组或文本__all__

下面是相关源代码的片段:

代码语言:javascript
运行
复制
    ALL_FIELDS = '__all__'
    if fields and fields != ALL_FIELDS and not isinstance(fields, (list, tuple)):
        raise TypeError(
            'The `fields` option must be a list or tuple or "__all__". '
            'Got %s.' % type(fields).__name__
        )

您不能在元组或包含字段的列表中添加“all”。

票数 31
EN

Stack Overflow用户

发布于 2016-12-09 15:20:45

正如@DanEEStart所说,DjangoRestFramework没有一种简单的方法将'all‘值扩展到字段,因为get_field_names方法似乎是设计以那种方式工作的。

但幸运的是,您可以重写此方法以允许一种简单的方法来包含所有字段和关系,而无需枚举大量字段。

我像这样覆盖这个方法:

代码语言:javascript
运行
复制
class ToppingSerializer(serializers.ModelSerializer):

    class Meta:
        model = Topping
        fields = '__all__'
        extra_fields = ['pizzas']

    def get_field_names(self, declared_fields, info):
        expanded_fields = super(ToppingSerializer, self).get_field_names(declared_fields, info)

        if getattr(self.Meta, 'extra_fields', None):
            return expanded_fields + self.Meta.extra_fields
        else:
            return expanded_fields

请注意,此方法只更改此序列化程序的行为,而extra_fields属性仅适用于此序列化程序类。

如果您有大量这样的序列化程序,您可以创建一个中间类,将这个get_fields_names方法包含在一个地方,并多次重用它们。有些人是这样的:

代码语言:javascript
运行
复制
class CustomSerializer(serializers.HyperlinkedModelSerializer):

    def get_field_names(self, declared_fields, info):
        expanded_fields = super(CustomSerializer, self).get_field_names(declared_fields, info)

        if getattr(self.Meta, 'extra_fields', None):
            return expanded_fields + self.Meta.extra_fields
        else:
            return expanded_fields


class ToppingSerializer(CustomSerializer):

    class Meta:
        model = Topping
        fields = '__all__'
        extra_fields = ['pizzas']

class AnotherSerializer(CustomSerializer):

    class Meta:
        model = Post
        fields = '__all__'
        extra_fields = ['comments']
票数 65
EN

Stack Overflow用户

发布于 2017-08-31 17:53:11

fields="__all__"选项可以手动指定一个附加字段,如下例所示。对于这个问题,这是迄今为止最干净的解决方案。

嵌套关系

http://www.django-rest-framework.org/api-guide/relations/#nested-relationships

代码语言:javascript
运行
复制
class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = '__all__'

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = '__all__'

我假设这将适用于同一页面上列出的任何其他相关字段选项:http://www.django-rest-framework.org/api-guide/relations/#serializer-relations

反向关系实例

代码语言:javascript
运行
复制
class TrackSerializer(serializers.ModelSerializer):
    album = AlbumSerializer(source='album_id')

    class Meta:
        model = Track
        fields = '__all__'

注释:使用DjangRESTFramework3.6.2版本创建的,可能会更改。如果将来的任何变化破坏了上面张贴的任何例子,请添加评论。

票数 30
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38245414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档