Django有Lower
函数,但这只适用于ASC
(升序)排序的查询。
示例URL:
'/api/locations/?ordering=-number,name'
我们使用了下面的模式:
from django.db.models.functions import Lower
class OrderingQuerySetMixin(object):
def get_queryset(self):
queryset = self.queryset
ordering = self.request.query_params.get('ordering', None)
if ordering:
if ordering.startswith('-'):
queryset = queryset.order_by(Lower(ordering[1:])).reverse()
else:
queryset = queryset.order_by(Lower(ordering))
return queryset
这个模式的问题是它不能对多个字段排序。这样做的唯一方法是将descending
参数直接传递给Lower
,并且lower在'-myfield'
之类的事情上失败,就像正常的Django ORM对降序排序一样。
下面是当前的模式,它接受多个参数来排序,但不处理降序:
class OrderingQuerySetMixin(object):
"""Return a case-insensitive ordered queryset."""
def eval_param(self, param):
if param.startswith('-'):
return param[1:]
else:
return param
def get_queryset(self):
queryset = self.queryset
ordering = self.request.query_params.get('ordering', None)
if ordering:
queryset = queryset.order_by(
*[Lower(self.eval_param(p)) for p in ordering.split(',')]
)
return queryset
#Import Lower function
from django.db.models.functions import Lower
#For Ascending order
queryset.order_by(Lower('field_name'))
#For Descending order
queryset.order_by(Lower('field_name').desc())