If I don't use the Lower()
function when sorting a queryset, then my queryset sorts uppercase and lowercase values separately. So if my queryset contains "Apples, Bananas, cherries, Oranges" and I use order_by('name')
then I get: "Apples, Bananas, Oranges, cherries". If I use order_by(Lower('name'))
then all works fine.
My problem is that my view sorts using MyModel.objects.all().order_by(order_by)
where order_by
is set using a user specified GET variable. Lower()
errors when the GET variable tries to sort in reverse order, eg order_by='-name'
I tried the following code but I get a traceback error when order_by='-name'
, but works fine when order_by='name'
: MyModel.objects.all().order_by(Lower(order_by))
I then tried something smarter, but now when order_by='-name'
then the queryset stops sorting alphabetically and just sorts using the object ID. But sorts fine when order_by='name'
.
Views.py
@login_required
def merchantgroups_show_all(request):
order_by = request.GET.get('order_by', 'name')
from django.db.models.functions import Lower
if order_by[0]=='-':
order_by = order_by[1:]
merchant_groups = MerchantGroup.objects.all().order_by('-'+Lower(order_by))
else:
merchant_groups = MerchantGroup.objects.all().order_by(Lower(order_by))
paginator = Paginator(merchant_groups,20)
page = request.GET.get('page')
merchant_groups2 = paginator.get_page(page)
return render(request, 'monzo/merchantgroups_show_all.html', {'merchant_groups': merchant_groups2,})
Any ideas on how to get Lower()
to work when the GET variable order_by
starts with a negative value?