使用django-filter进行不区分大小写的排序

时间:2015-08-06 17:44:03

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

是否可以case-insensitive使用 Django-rest-framework 进行first_name排序。

以下是代码:

import django_filter

class PersonFilter(django_filters.FilterSet):
    class Meta:
        model = Person
        fields = ('first_name_lower',)
        order_by = ('first_name_lower',)

class PersonViewSet(BaseModelViewSet):
    queryset = Person.objects.all()
    permission_classes = (permissions.IsAuthenticated,)
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = PersonFilter

使用case-insensitive进行django-filter订购是否有简单方法?

Here django-filter包含不区分大小写搜索的文档,但排序没有。

在Django文档中,代码对此有点迟钝,这让我想知道它是否存在django-filter。这里是关于如何使用Django ORM实现它的Django文档代码片段:

>>> from django.db.models.functions import Lower
>>> MyModel.objects.order_by(Lower('myfield'))

4 个答案:

答案 0 :(得分:1)

您可能希望将OrderingFilter作为子类并将其用作filter_backend,以便您可以重复使用该代码。

from rest_framework.filters import OrderingFilter
from django.db.models.functions import Lower

class CaseInsensitiveOrderingFilter(OrderingFilter):
    def filter_queryset(self, request, queryset, view):
        ordering = self.get_ordering(request, queryset, view)

        if ordering is not None:
            if ordering.startswith('-'):
                queryset = queryset.order_by(Lower(ordering[1:])).reverse()
            else:
                queryset = queryset.order_by(Lower(ordering))
        return queryset


class PersonViewSet(ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = MySerializer
    permission_classes = (permissions.IsAuthenticated,)
    filter_backends = (CaseInsensitiveOrderingFilter,)

答案 1 :(得分:0)

可以通过覆盖case-insensitive类上的get_queryset方法来完成ModelViewSet搜索。

适用于降序升序 case-insensitive排序。

# Example URL's
'/api/people/?ordering=-first_name'
'/api/people/?ordering=first_name'

以下是代码:

class PersonViewSet(ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = MySerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        queryset = self.queryset
        ordering = self.request.query_params.get('ordering', None)
        if ordering is not None:
            from django.db.models.functions import Lower
            if ordering.startswith('-'):
                queryset = queryset.order_by(Lower(ordering[1:])).reverse()
            else:
                queryset = queryset.order_by(Lower(ordering))
        return queryset

from django.db.models.functions import Lower仅适用于升序,因此如果您需要降序,基本上可以在其上调用.reverse()

答案 2 :(得分:0)

您可以替换Create.cshtml的{​​{1}}函数,并在filter中设置排序参数:

OrderingFilter

答案 3 :(得分:-1)

在django-rest列表视图中使用ordering和ordering_fields参数 - http://www.django-rest-framework.org/api-guide/filtering/#specifying-a-default-ordering

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = ('username', 'email')
    ordering = ('username',)