提问者:小点点

Django Rest框架:动态返回字段子集


正如blogpost关于设计实用的RESTful API的最佳实践中所推荐的,我想在基于Django Rest框架的API中添加一个fields查询参数,该参数允许用户仅选择每个资源的字段子集。

序列化程序:

class IdentitySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Identity
        fields = ('id', 'url', 'type', 'data')

常规查询将返回所有字段。

获取/identities/

[
  {
    "id": 1,
    "url": "http://localhost:8000/api/identities/1/",
    "type": 5,
    "data": "John Doe"
  },
  ...
]

具有fields参数的查询应仅返回字段的子集:

获取/identities/?fields=id,data

[
  {
    "id": 1,
    "data": "John Doe"
  },
  ...
]

包含无效字段的查询应忽略无效字段或引发客户端错误。

这是不是可能的?如果没有,实现这一点最简单的方法是什么?是否有一个第三方包已经做到这一点?


共1个答案

匿名用户

您可以重写序列化程序__init__方法,并根据查询参数动态设置fields属性。您可以在整个上下文中访问request对象,并将其传递给序列化程序。

下面是一个来自Django Rest框架文档示例的copy&paste:

from rest_framework import serializers

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

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

        fields = self.context['request'].query_params.get('fields')
        if fields:
            fields = fields.split(',')
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)


class UserSerializer(DynamicFieldsModelSerializer, serializers.HyperlinkedModelSerializer):

    class Meta:
        model = User
        fields = ('url', 'username', 'email')