我有一个带有 ?ordering=name,type
的 api我希望名称和类型都不区分大小写
class IngredientListAPIView(ListAPIView):
queryset = Ingredient.objects.all()
serializer_class = IngredientListSerializer
filter_backends = [OrderingFilter]
从
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']
更简单的方法是直接用
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'))
我发现这个问题的最佳答案:在数据库中创建一个不区分大小写的新排序规则,如下>>
创建排序 en_ci (provider = icu, locale = 'en-US@colStrength=secondary');
然后在您的模型中使用它:
title = models.CharField(max_length=250, null=True, Blank=False, db_collation='en_ci')