Django (DRF):如何进行不区分大小写的排序

问题描述 投票:0回答:3

我有一个带有 ?ordering=name,type

的 api

我希望名称和类型都不区分大小写

class IngredientListAPIView(ListAPIView):
    queryset = Ingredient.objects.all()
    serializer_class = IngredientListSerializer
    filter_backends = [OrderingFilter]
django django-rest-framework
3个回答
3
投票

https://github.com/encode/django-rest-framework/issues/3280

得到解决方案
from django.db.models.functions import Lower
from rest_framework.filters import OrderingFilter


class CaseInsensitiveOrderingFilter(OrderingFilter):

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

        if ordering:
            new_ordering = []
            for field in ordering:
                if field.startswith('-'):
                    new_ordering.append(Lower(field[1:]).desc())
                else:
                    new_ordering.append(Lower(field).asc())
            return queryset.order_by(*new_ordering)

        return queryset

然后在ListView中使用它

class IngredientListAPIView(ListAPIView):
    queryset = Ingredient.objects.all()
    serializer_class = IngredientListSerializer
    filter_backends = [SearchFilter,CaseInsensitiveOrderingFilter]
    search_fields = ['name','slug']

1
投票

更简单的方法是直接用

Lower
db model 函数下单

from django.db.models.functions import Lower
# ...
    
class UsersViewSet(models.Model):
    serializer_class = UserSerializer
    def get_queryset(self):
        return super().get_queryset().order_by(Lower('username'))

0
投票

我发现这个问题的最佳答案:在数据库中创建一个不区分大小写的新排序规则,如下>>

创建排序 en_ci (provider = icu, locale = 'en-US@colStrength=secondary');

然后在您的模型中使用它:

title = models.CharField(max_length=250, null=True, Blank=False, db_collation='en_ci')

© www.soinside.com 2019 - 2024. All rights reserved.