在Django模板中,是否可以对一组相关项目进行排序?
也就是说,对于下面的代码(为了清晰起见省略了HTML标记):
{% for event in eventsCollection %}
{{ event.location }}
{% for attendee in event.attendee_set.all %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
这几乎完全显示了我想要的内容。唯一我想要改变的是参与者名单按姓氏排序。我尝试过如下:
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_set.order_by__last_name %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
很遗憾,上面的语法不起作用(它生成一个空列表),我想过其他的变化方式,但没有一种是有效的(报告了许多语法错误,但没有成功)。当然,我可以在我的视图中生成某种排序后的与会者列表数组,但那是一个丑陋而脆弱的解决方案(我提到了它很丑陋,你们明白吧)。无需多言,我已经查看了在线文档并搜索了Stack Overflow和django-user的存档,但都没有找到有用的信息(啊,如果查询集是一个字典dictsort就可以完成这项工作,但它不是,也不能)。
编辑添加额外的想法,接受Tawmas的答案后。
Tawmas恰好解决了我提出的问题-虽然解决方案不是我期望的。因此,我学到了一种在其他情况下也可以使用的有用技巧。
Tom的答案提出了一种我已经在我的原始帖子中提到并暂时拒绝作为"丑陋"的方法。"丑陋"是一种直觉反应,我想澄清它的问题所在。在这样做时,我意识到它是一个丑陋的方法,是因为我固定在将查询集传递到模板进行渲染这个想法上了。如果我放宽这个要求,就有一种不丑陋的方法可以解决问题。
我还没有尝试过这个方法,但假设不是传递查询集,而是视图代码迭代查询集生成一个事件列表,然后装饰每个事件与相应的与会者查询集,这些查询集是按所需方式排序(或过滤、或其他)。就像这样:
eventCollection = []
events = Event.object.[filtered and sorted to taste]
for event in events:
event.attendee_list = event.attendee_set.[filtered and sorted to taste]
eventCollection.append(event)
现在模板变成了:
{% for event in events %}
{{ event.location }}
{% for attendee in event.attendee_list %}
{{ attendee.first_name }} {{ attendee.last_name }}
{% endfor %}
{% endfor %}
缺点是视图必须一次“实际化”所有事件,如果有大量事件可能会成为问题。当然可以添加分页,但这会使视图变得更加复杂。优点是“准备要显示的数据”的代码在视图中,这正是它应该所在的地方,让模板专注于对视图提供的数据进行格式化以供显示。这是正确和适当的。
因此,我的计划是在大表格上使用Tawmas的技术,在小表格上使用上述技术,大和小的定义留给读者(微笑)。
dictsortreversed
:https://docs.djangoproject.com/en/dev/ref/templates/builtins/#dictsortreversed - Mickaëldictsort
。有趣的是,它似乎在查询集上运行良好。 - mlissner{% for attendee in event.attendee_set.all|dictsort:"last_name" %}
对出席者进行排序,但{% for attendee in event.attendee_set.all | dictsort:"last_name" %}
尝试对 for 循环的输出进行排序并破坏了for
。 - mattsl