【问题标题】:Is there a way in Django Rest Framework to deliver only specific attributes?Django Rest Framework 中有没有办法只提供特定的属性?
【发布时间】:2021-01-04 23:42:37
【问题描述】:

在构建大型 Web 后端时,我们面临的问题是模型具有很多属性。由于我们想减少响应的大小以提高效率,我们为我们的模型使用不同的序列化器。以这个简单的模型为例:

class Address(models.Model):
    country_id = models.ForeignKey(Country, on_delete=models.PROTECT)
    postal_code = models.CharField(max_length=10)
    street = models.CharField(max_length=176)
    number = models.CharField(max_length=20)
    additional = models.CharField(max_length=256, blank=True, default='')
    city = models.CharField(max_length=176)
    state = models.CharField(max_length=50)

    user = models.ForeignKey('user.User', on_delete=models.CASCADE)

仅就这一点而言,我们有一个 ID 序列化器、一个字符串序列化器(用于传递可用字符串)、一个最小序列化器(用于多个地址的列表)、一个 DetailSerializer(深度 = 1 用于获取国家和用户详细信息...

现在,由于这种复杂性,我们面临几个问题,并考虑重组 api 以在请求中包含所需的字段。 django + drf可以做到这一点吗?我们相信在Content Negotiation 下可以找到一些东西,但这是一个不同的主题。

【问题讨论】:

  • GraphQL (django-graphene) 怎么样
  • 如果我看到正确使用它,我们需要重写整个后端?

标签: django django-rest-framework


【解决方案1】:

您可以像这样动态修改字段:

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)

欲了解更多信息,请访问drf docs

【讨论】:

    猜你喜欢
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 2019-04-30
    • 2017-03-04
    • 2021-05-02
    • 2018-09-13
    • 2020-12-24
    相关资源
    最近更新 更多