首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用django-过滤器做不区分大小写的排序

用django-过滤器做不区分大小写的排序
EN

Stack Overflow用户
提问于 2015-08-06 17:44:03
回答 4查看 5.4K关注 0票数 7

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

以下是代码:

代码语言:javascript
复制
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为不区分大小写的search提供文档,但对于ordering没有文档。

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

代码语言:javascript
复制
>>> from django.db.models.functions import Lower
>>> MyModel.objects.order_by(Lower('myfield'))
EN

回答 4

Stack Overflow用户

发布于 2015-11-16 07:19:53

您可能希望对OrderingFilter进行子类化,并将其用作您的filter_backend,以便您可以重用代码。

代码语言:javascript
复制
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,)
票数 4
EN

Stack Overflow用户

发布于 2015-08-06 21:53:06

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

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

代码语言:javascript
复制
# Example URL's
'/api/people/?ordering=-first_name'
'/api/people/?ordering=first_name'

下面是代码:

代码语言:javascript
复制
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()

票数 0
EN

Stack Overflow用户

发布于 2019-07-25 07:08:40

您可以替换filter函数的OrderingFilter,并在Lower中设置排序参数

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31862420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档