Как отсортировать список объектов в шаблоне в алфавитном порядке?
Я хочу отобразить список объектов в классе Django generic display view ListView
. И, чтобы сделать его красивее, я стараюсь сортировать его в алфавитном порядке. Поэтому я использую встроенный тег dictsort
для сортировки списка.
Вот краткое изложение кода, который я использовал:
{% for item in object_list|dictsort:"name" %}
...
{% empty %}
...
{% endfor %}
Проблема заключается в том, что он сортирует имена в соответствии со значениями ASCII символов, что означает, что bigcaps и smallcaps сортируются по-разному. Вот пример:
Bob
Eve
alice
zoe
И, что я хотел бы иметь, так это следующее:
alice
Bob
Eve
zoe
Я просмотрел документацию и несколько вопросов в SO, но без успеха. Так что, если у кого-то есть способ достичь этого, я был бы чрезвычайно благодарен.
2 ответов:
Вам нужно будет написать пользовательский фильтр, который сортирует по нижнему регистру. Это довольно просто:
@register.filter def sort_lower(lst, key_name): return sorted(lst, key=lambda item: getattr(item, key_name).lower())
Но если ваш список представляет собой набор объектов из базы данных, вы не должны сортировать их в Python - вы должны заставить базу данных возвращать их в нужном порядке.
Edit
Как вы используете фильтр? Он должен быть точно таким же, как и диктсорт:
object_list|sort_lower:"name"
.Для сортировки набора запросов в базе данных можно использовать метод
extra
для добавления строчная версия поля:MyModel.objects.all().extra(select={'lower_name': 'LOWER(NAME)'}, order_by='lower_name')
На самом деле, я посмотрел на исходный код
dictsort
в.../lib/python2.7/site-packagesdjango/template/defaultfilters.py
. И я только что добавил настроенный методcmp
:@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 ''
Этот способ позволяет сортировать по подполям (напр.
field1.field2
) что было необходимо в моем случае.
Comments