如何按字母顺序对模板中的对象列表进行排序?

时间:2014-02-02 14:09:50

标签: django django-templates django-template-filters

我想在Django通用显示视图ListView类中显示对象列表。并且,为了使它更漂亮,我尝试按字母顺序对其进行排序。因此,我使用内置的dictsort标记对列表进行排序。

以下是我使用的代码摘要:

{% for item in object_list|dictsort:"name" %}
  ...
{% empty %}
  ...
{% endfor %}

问题在于它根据字符的ASCII值对名称进行排序,这意味着bigcaps和smallcaps的排序方式不同。这是一个例子:

Bob
Eve
alice
zoe

而且,我想要的是以下内容:

alice
Bob
Eve
zoe

我在SO中查看了文档和几个问题,但没有成功。所以,如果有人有办法实现这一目标,我将非常感激。

4 个答案:

答案 0 :(得分:3)

您需要编写一个按小写字母排序的自定义过滤器。这很简单:

@register.filter
def sort_lower(lst, key_name):
    return sorted(lst, key=lambda item: getattr(item, key_name).lower())

但是如果你的列表是数据库中的一组对象,那么你不应该用Python对它们进行排序 - 你应该让数据库按照你想要的顺序返回它们。

修改

您是如何使用过滤器的?它应与dictsort one完全相同:object_list|sort_lower:"name"

要对数据库中的查询集进行排序,可以使用extra方法添加该字段的小写版本:

MyModel.objects.all().extra(select={'lower_name': 'LOWER(NAME)'}, order_by='lower_name')

答案 1 :(得分:1)

事实上,我查看了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)进行排序。

答案 2 :(得分:1)

我知道这是一个老问题,但是我发现排序不区分大小写的列表的最简单方法是:

name_of_list.sort(key = str.lower)

请参阅链接以供参考: https://www.afternerd.com/blog/python-sort-list/

您可以使用以下代码对其进行测试:

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)

然后,当您在模板中显示列表时,项目将已经排序。

答案 3 :(得分:1)

一个非常老的问题,但是这个问题才刚刚出现。只需将.lower添加到dictsort中即可,例如:

{% for item in object_list|dictsort:"name.lower" %}