DRF API 返回带有过滤列表的列表 [英] DRF API return a list with filtered lists

查看:22
本文介绍了DRF API 返回带有过滤列表的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

返回的数据是一个包含所有字段的列表.我希望将数据分隔在主列表内的不同列表中.例如,在今天之前的日期和今天之后的日期过滤的数据列表.我可以编写两个端点并在查询集中过滤数据,但这需要两个单独的 API 调用.

视图集:

class StudyPageViewSet(viewsets.ModelViewSet):"""研究通过 API 创建、读取、更新、删除."""模型 = 研究serializer_class = StudyPageSerializerpermission_classes = (IsAuthenticated, IsAuthorPermission,)def get_queryset(self):返回 Study.on_site.all()

序列化器:

class StudyPageSerializer(serializers.ModelSerializer):元类:模型 = 研究字段 = ('id', 'title', 'date', 'location')read_only_fields = ('id',)

结果应该是:

<预><代码>[{list_before_today":[{"id":"5001","title":"无"},{"id":"5002","title":"釉面"},]},{list_after_today":[{"id":"5003","title":"无"},{"id":"5004","title":"釉面"},]},]

当前输出:

<预><代码>[{身份证":588,"title": "title",.. : ..},{身份证":590,"title": "title2",.. : ..},]

ps.点代表其他字段.

解决方案

默认情况下,当您在 ModelViewSet 视图中调用 GET 请求时,它会调用 list 方法.在列表方法中,Rest 框架确实使用 Model 创建一个查询集来查询数据,然后将其传递给 Serializer 以序列化数据然后返回它,这就是为什么你得到这个:

[{身份证":588,"title": "title",.. : ..},{身份证":590,"title": "title2",.. : ..},]

因此,要按照您的预期获得响应,您必须覆盖该 list 方法以获取具有您预期格式的响应,如下所示:

从日期时间导入日期从 rest_framework 导入状态类 StudyPageViewSet(viewsets.ModelViewSet):"""研究通过 API 创建、读取、更新、删除."""模型 = 研究serializer_class = StudyPageSerializerpermission_classes = (IsAuthenticated, IsAuthorPermission,)def get_queryset(self):返回 Study.on_site.all()定义列表(自我,请求):查询集 = self.get_queryset()今天 = date.today()输出 = [{"list_before_today": self.get_serializer(queryset.filter(date__lt=today), many=True).data}, {"list_after_today": self.get_serializer(queryset.filter(date__gt=today), many=True).data}]返回响应(输出,状态=status.HTTP_200_OK)

这只是一个想法,因此您必须与您的代码保持一致才能使其工作.我也不建议你这样做,因为 ModelViewSet 是由 Django Rest Framework 定义好的,如果你想得到那个响应,你也可以创建另一个 APIView 来处理它.

希望有帮助!

The data that is returned is one list with all fields. I want the data to be separated in different lists inside the main list. For example a list of data that is filtered on the date before today and a list after the date of today. I could write two endpoints and have the data filtered in the queryset, but that would take two separate API calls.

The viewset:

class StudyPageViewSet(viewsets.ModelViewSet):
    """
    Study create, read, update, delete over API.
    """
    model = Study
    serializer_class = StudyPageSerializer
    permission_classes = (IsAuthenticated, IsAuthorPermission,)

    def get_queryset(self):
        return Study.on_site.all()

The Serializer:

class StudyPageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Study
        fields = ('id', 'title', 'date', 'location')
        read_only_fields = ('id',)

Outcome should be like:

[ 
   { 
      "list_before_today":[ 
         { 
            "id":"5001",
            "title":"None"
         },
         { 
            "id":"5002",
            "title":"Glazed"
         },

      ]
   },
   { 
      "list_after_today":[ 
         { 
            "id":"5003",
            "title":"None"
         },
         { 
            "id":"5004",
            "title":"Glazed"
         },

      ]
   },

]

Current output:

[
    {
        "id": 588,
        "title": "title",
        .. : ..
    },
    {
        "id": 590,
        "title": "title2",
        .. : ..
    },
]

ps. the dots represent the other fields.

解决方案

By default, when you call GET request into ModelViewSet view, it will call list method. Inside list method, Rest framework does use the Model to create a queryset to query data and then pass it into Serializer to serialize the data and then return it, that's why you got this:

[
    {
        "id": 588,
        "title": "title",
        .. : ..
    },
    {
        "id": 590,
        "title": "title2",
        .. : ..
    },
]

So to get the response as your expected, you have to override that list method to get the response with the format as your expected, like so:

from datetime import date

from rest_framework import status

class StudyPageViewSet(viewsets.ModelViewSet):
    """
    Study create, read, update, delete over API.
    """
    model = Study
    serializer_class = StudyPageSerializer
    permission_classes = (IsAuthenticated, IsAuthorPermission,)

    def get_queryset(self):
        return Study.on_site.all()

    def list(self, request):
        queryset = self.get_queryset()
        today = date.today()

        output = [{
            "list_before_today": self.get_serializer(queryset.filter(date__lt=today), many=True).data
        }, {
            "list_after_today": self.get_serializer(queryset.filter(date__gt=today), many=True).data
        }]


        return Response(output, status=status.HTTP_200_OK)

This is just the idea so you have to align with your code to make it work. I'm also not recommend you to do that because ModelViewSet is well-defined by Django Rest Framework, if you want to get that response, you also can create another APIView to handle that.

Hope that helps!

这篇关于DRF API 返回带有过滤列表的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆