使用Djangoffi执行不区分大小写的排序

2024-09-27 19:32:23 发布

您现在位置:Python中文网/ 问答频道 /正文

使用Django rest框架是否可以通过first_name进行case-insensitive排序。在

代码如下:

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

有没有一种简单的方法可以用django-filter进行case-insensitive排序?在

Heredjango filter有文档用于不区分大小写的搜索,但没有用于排序的文档。在

在Django文档中,代码对此有些迟钝,这让我怀疑它是否存在于django-filter中。下面是关于如何使用Django ORM的Django docs代码片段:

^{pr2}$

Tags: django代码name文档排序filterlowerfilters
3条回答

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

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

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

代码如下:

^{pr2}$

from django.db.models.functions import Lower只对升序有效,所以如果需要降序,基本上可以调用.reverse()。在

您可能希望将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,)

您可以替换OrderingFilterfilter函数,并在Lower中设置排序参数:

class CaseInsensitiveOrderingFilter(django_filters.OrderingFilter):
    def filter(self, qs, value):
        if value in django_filters.constants.EMPTY_VALUES:
            return qs

        ordering = [Lower(self.get_ordering_value(param)) for param in value]
        return qs.order_by(*ordering)

相关问题 更多 >

    热门问题