I want to display a list of objects in a Django generic display view ListView class. And, to make it prettier, I try to sort it in alphabetic order. So, I use the built-in dictsort tag to sort the list.
Here is the summary of the code I used:
{% for item in object_list|dictsort:"name" %}
...
{% empty %}
...
{% endfor %}
The problem is that it sorts the names according to the ASCII values of the characters, meaning that bigcaps and smallcaps are sorted differently. Here is an example:
Bob
Eve
alice
zoe
And, what I would like to have is the following:
alice
Bob
Eve
zoe
I looked the documentation and several questions in SO, with no success. So, if someone has a way to achieve this, I would be extremely grateful.
You'll need to write a custom filter which sorts by lower case. It's pretty simple:
@register.filter
def sort_lower(lst, key_name):
return sorted(lst, key=lambda item: getattr(item, key_name).lower())
But if your list is a set of objects from the database, you shouldn't really be sorting them in Python - you should get the database to return them in the order you want.
Edit
How are you using the filter? It should be exactly the same as the dictsort one: object_list|sort_lower:"name".
To sort the queryset in the database, you can use the extra method to add a lower-case version of the field:
MyModel.objects.all().extra(select={'lower_name': 'LOWER(NAME)'}, order_by='lower_name')
A very old question, but the issue just came up for me. Just add .lower to dictsort, e.g.:
{% for item in object_list|dictsort:"name.lower" %}
I know this is an old question, but the easiest way I see to sort a list case insensitive is:
name_of_list.sort(key=str.lower)
See link for reference: https://www.afternerd.com/blog/python-sort-list/
You can test it using this code:
my_list = ["alice", "Bob", "eve", "Zoe"]
my_list.sort()
print("case sensitive list:")
print(my_list)
my_list.sort(key=str.lower)
print("case insensitive list:")
print(my_list)
Then when you display your list in templates the items will already be sorted.
In fact, I looked at the original code of dictsort in .../lib/python2.7/site-packagesdjango/template/defaultfilters.py. And, I just added a customized cmp method:
@register.filter
def sort_lower(value, arg):
try:
return sorted(value, key=Variable(arg).resolve,
cmp=lambda x,y: cmp(x.lower(), y.lower()))
except (TypeError, VariableDoesNotExist):
return ''
This way allow to sort by subfields (e.g. field1.field2) which was needed in my case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With