【问题标题】:Django REST Framework FilteringDjango REST 框架过滤
【发布时间】:2017-05-27 04:31:56
【问题描述】:

我正在使用Django REST Framework Generic Filtering 并希望实现两个目标:

  1. 仅获取查询集的最后一个结果。例如,http://my_server/users/?last 将只返回最后一个用户(id 最大的用户)。
  2. 获取查询集中的结果数。例如,http://my_server/users/?category=admin&count 将返回 number 管理员用户。

这样做最优雅的方式是什么?

【问题讨论】:

    标签: python django rest django-rest-framework django-filter


    【解决方案1】:

    last 实际上是所需 ID 的别名。在这里使用查询参数没有意义,因为您的 url 结构已经允许通过 id 检索单个对象。覆盖get_object() 将允许您使用/api/users/last。

    def get_object(self):
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
        lookup = self.kwargs.get(lookup_url_kwarg, None)
    
        if lookup == 'last':
            queryset = self.filter_queryset(self.get_queryset())
            return queryset.order_by('pk').last()
    
        return super(UserViewSet, self).get_object()
    

    如前所述,对于所有用户的计数,分页是您获取该数字的一种内置方式。如果不想使用分页,也可以使用list_route()s 和detail_route()s 进行自定义操作或路由。下面添加了一个/api/users/count 路由。

    @list_route(methods=['get'])
    def count(self, request):
        queryset = self.filter_queryset(self.get_queryset())
    
        return Response({'count': queryset.count()})
    

    【讨论】:

    • 太好了,谢谢!
    【解决方案2】:

    您可以尝试创建rest_framework.filters.DjangoFilterBackend 的自定义子类。他们定义了一个filter_queryset 方法来执行过滤,例如:

    from rest_framework import filters
    
    from .models import User
    
    class UserFilter(filters.DjangoFilterBackend):
        def filter_queryset(self, request, queryset, view):
            if 'last' in request.QUERY_PARAMS:
                queryset = User.objects.filter(pk=queryset.last().pk)
            # pass it up for the built-in / other filters
            return super(UserFilter, self).filter_queryset(
                request, queryset, view
            )
    

    那么在你的UserViewSet,有:

    # ...
    serializer_class = UserSerializer
    filter_backends = (UserFilter,)
    # ...
    

    至于显示计数,我建议查看Django rest framework pagination docs。设置好后,它会自动将next、previous、count 和results 值放入返回给用户的 JSON 中。

    【讨论】:

      猜你喜欢
      • 2012-12-24
      • 2014-02-17
      • 2017-05-03
      • 1970-01-01
      • 2014-09-11
      • 2018-11-05
      • 2017-10-26
      • 2018-05-17
      • 2017-10-06
      相关资源
      最近更新 更多