【问题标题】:DRF API return a list with filtered listsDRF API 返回一个带有过滤列表的列表
【发布时间】:2020-01-26 21:22:05
【问题描述】:

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

视图集:

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()

序列化器:

class StudyPageSerializer(serializers.ModelSerializer):

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

结果应该是这样的:

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

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

      ]
   },

]

当前输出:

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

ps。点代表其他字段。

【问题讨论】:

  • 你能显示当前的响应格式吗?
  • @ToanQuocHo 是的,我会把它添加到问题中

标签: python django api django-rest-framework


【解决方案1】:

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

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

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

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)

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

希望有帮助!

【讨论】:

  • 最后我使用了 ReadOnlyViewset 来满足我的需求。感谢您提供这个有用的答案
猜你喜欢
  • 2022-12-05
  • 2022-06-15
  • 2023-02-26
  • 1970-01-01
  • 2018-12-13
  • 2019-04-16
  • 2015-12-15
  • 2014-01-24
  • 2017-08-07
相关资源
最近更新 更多