django rest framework order listview by serializer specific field

时间:2017-07-20 06:15:25

标签: django python-3.x django-rest-framework

所以我目前使用django rest框架构建了一个Drink序列化程序。它有一个字段count_need,我使用SerializerMethodField获得,它不是Drink模型的一部分。它还有一个timestamp字段,它是模型的一部分。如何根据timestamp等获取请求中的参数,count_need/api/drink/?ordering=timestamp订购ListAPI视图。目前,我已经在ListAPI视图ordering_fields = ('count_need', 'timestamp', )中指定了排序字段,但它似乎没有在任一查询上排序apiview。我可以timestamp通过get_queryset方法对其进行排序,但这不适用于count_need,因为它不属于模型。

1 个答案:

答案 0 :(得分:0)

您可以尝试覆盖View上的get_queryset方法,并在queryset上为count_need添加带注释的字段。我认为这样会更好,因为在大型列表的SQL中可能会更快,并且可以使用其余框架的内置OrderingFilter。

示例:

from django.db.models import Count

class MyView(APIView):
    def get_queryset(self):
        qs = self.queryset
        qs = qs.annotate(count_need=Count('need'))
        return qs

推荐阅读:
https://docs.djangoproject.com/en/1.11/topics/db/aggregation/#aggregations-and-other-queryset-clauses

另一种选择是在Python中实现一些自定义排序,而不是使用Django ORM。您可以通过覆盖ListAPI视图上的list方法来执行此操作。

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        serializer_data = serializer.data
        sorted_serializer_data = sorted(serializer_data, key=lambda x: x['count_need'])
        return self.get_paginated_response(sorted_serializer_data)

    serializer = self.get_serializer(queryset, many=True)
    serializer_data = serializer.data
    sorted_serializer_data = sorted(serializer_data, key=lambda x: x['count_need'])
    return Response(sorted_serializer_data)