Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django Rest框架:动态返回字段子集 问题_Django_Django Rest Framework - Fatal编程技术网

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

Django Rest框架:动态返回字段子集 问题,django,django-rest-framework,Django,Django Rest Framework,正如blogpost中建议的那样,我想向基于Django Rest框架的API添加一个fieldsquery参数,该参数使用户能够仅选择每个资源的字段子集 例子 序列化程序: class IdentitySerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Identity fields = ('id', 'url', 'type', 'data')

正如blogpost中建议的那样,我想向基于Django Rest框架的API添加一个
fields
query参数,该参数使用户能够仅选择每个资源的字段子集

例子 序列化程序:

class IdentitySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Identity
        fields = ('id', 'url', 'type', 'data')
常规查询将返回所有字段

GET/identies/

[
  {
    "id": 1,
    "url": "http://localhost:8000/api/identities/1/",
    "type": 5,
    "data": "John Doe"
  },
  ...
]
使用
字段
参数的查询应仅返回字段的子集:

GET/identifies/?fields=id,data

[
  {
    "id": 1,
    "data": "John Doe"
  },
  ...
]
具有无效字段的查询应忽略无效字段或引发客户端错误

目标
这有可能是开箱即用的吗?如果没有,最简单的实现方法是什么?是否有第三方软件包已经这样做了?

您可以覆盖序列化程序
\uuuu init\uuuu
方法,并根据查询参数动态设置
字段
属性。您可以在整个上下文中访问传递给序列化程序的
请求
对象

以下是有关此问题的复制和粘贴:

配置新的分页序列化程序类 生成动态序列化程序 最后,将homemage mixin用于ApiView 要求 现在,当您请求一个资源时,您可以添加一个参数
fields
,以便在url中仅显示指定的字段。
/?字段=字段1,字段2

您可以在此处找到提醒:

serializers.py 视图.py
此功能可从中获得

按如下方式声明序列化程序:

from rest_framework.serializers import ModelSerializer
from drf_queryfields import QueryFieldsMixin

class MyModelSerializer(QueryFieldsMixin, ModelSerializer):
    ...
现在可以使用查询参数指定字段(客户端):

GET /identities/?fields=id,data
也可以进行排除筛选,例如返回除id以外的所有字段:


免责声明:我是作者/维护者

我们在中提供的功能


如果您使用我们的序列化程序,您只需在查询中传递
?fields=x,y,z
参数。

您可以尝试,它支持动态字段(包含、排除)、嵌入/侧载对象、筛选、排序、分页等。

对于嵌套数据,我正在使用Django Rest框架和

这允许您限制在父对象和子对象上返回的字段。自述文件中的说明很好,只是需要注意以下几点:

URL似乎需要/like this'/person/?expand=country&fields=id,name,country'而不是自述文件中写的“/person?expand=country&fields=id,name,country”

嵌套对象的命名及其相关名称需要完全一致,否则不需要这样做


如果您有“许多”,例如,一个国家可以有许多州,则需要在序列化程序中设置“许多”:如文档中所述为True。

如果您想要像GraphQL这样灵活的东西,可以使用。它支持嵌套数据(平面数据和可编辑数据)

示例

从rest\u框架导入序列化程序
从django.contrib.auth.models导入用户
从django_restql.mixin导入DynamicFieldsMixin
类UserSerializer(DynamicFieldsMixin,serializers.ModelSerializer):
类元:
模型=用户
字段=('id','username','email','groups')
常规请求返回所有字段

GET/users

    [
      {
        "id": 1,
        "username": "yezyilomo",
        "email": "yezileliilomo@hotmail.com",
        "groups": [1,2]
      },
      ...
    ]
另一方面,带有
query
参数的请求只返回 字段:

GET/users/?query={id,username}

    [
      {
        "id": 1,
        "username": "yezyilomo"
      },
      ...
    ]
使用django restql可以访问任何级别的嵌套字段。例如

GET/users/?query={id、用户名、加入日期{year}

    [
      {
        "id": 1,
        "username": "yezyilomo",
        "date_joined": {
            "year": 2018
        }
      },
      ...
    ]
对于iterable嵌套字段,例如用户上的组

GET/users/?query={id,用户名,组{id,name}}

    [
      {
        "id": 1,
        "username": "yezyilomo",
        "groups": [
            {
                "id": 2,
                "name": "Auth_User"
            }
        ]
      },
      ...
    ]

[DRF Documentation][1]中建议的解决方案对我很有效,但是当我从视图调用序列化程序时,我使用了:

class SomeView(ListAPIView):
    def get(self, request, *args, **kwargs):
        qry=table.objects.filter(column_value=self.kwargs['urlparameter'])
        fields=['DBcol1','DBcol2','DBcol3']    
        serializer=SomeSerializer(qry,many=True,fields=fields)
我必须添加
many=True
,否则它就不起作用了

  [1]: https://www.django-rest-framework.org/api-guide/serializers/#example

另一种选择是使用GraphWrap:


通过将/graphql添加到您的urlpatterns,您可以使用完全兼容的graphql可查询API为REST API添加层。

我终于实现了这一点,它工作得非常完美!谢谢最后,我为此编写了一个mixin,合成比子类化更灵活:)在Django的最新版本中,您需要将
QUERY\u PARAMS
更改为
QUERY\u PARAMS
,但除此之外,这就像一个符咒。您可能应该检查
请求是否作为
上下文的成员存在。虽然在生产环境中是这样,但在运行手动创建对象的单元测试时却不是这样。仅供参考:此示例是此处找到的DRF文档的逐字副本:不提供指向原始作者的链接是一种不好的形式此答案是从其复制而来的。此答案发布后已得到改进。您好。这和(在所选答案的评论中链接的)有什么区别?谢谢,我看了一下这个实现,它看起来是相同的基本思想。但是
dbrgn
实现有一些不同:1。不支持使用
字段排除=按键1、按键2
。2.还修改GET请求上下文之外的序列化程序,这可以并且将中断一些PUT/POST请求。3.不使用例如
fields=key1&fields=key2
来累积字段,这对于ajax应用程序来说是一个不错的选择。它还具有零测试覆盖率,这在OSS中有些不寻常。@wim您的库支持哪些版本的DRF和Django?我在docs.Django 1.7-1.11+中没有找到任何东西,基本上是DRF支持的任何配置。此注释可能已过时,因此请检查.Works对我来说非常有用:Django==2.2.7,djangorestframework==3.10.3,djangorestframework queryfields==1.0.0
GET /identities/?fields=id,data
GET /identities/?fields!=id
    [
      {
        "id": 1,
        "username": "yezyilomo",
        "email": "yezileliilomo@hotmail.com",
        "groups": [1,2]
      },
      ...
    ]
    [
      {
        "id": 1,
        "username": "yezyilomo"
      },
      ...
    ]
    [
      {
        "id": 1,
        "username": "yezyilomo",
        "date_joined": {
            "year": 2018
        }
      },
      ...
    ]
    [
      {
        "id": 1,
        "username": "yezyilomo",
        "groups": [
            {
                "id": 2,
                "name": "Auth_User"
            }
        ]
      },
      ...
    ]
class SomeView(ListAPIView):
    def get(self, request, *args, **kwargs):
        qry=table.objects.filter(column_value=self.kwargs['urlparameter'])
        fields=['DBcol1','DBcol2','DBcol3']    
        serializer=SomeSerializer(qry,many=True,fields=fields)
  [1]: https://www.django-rest-framework.org/api-guide/serializers/#example