我有一个在模板中呈现的“促销”事件的查询集。这些促销活动中的每一个也有一个或多个约会。我想要做的是显示第一次和最后一次约会的日期。
到目前为止,使用“first”标签有效。但是,使用“last”标记会导致:
TemplateSyntaxError异常值: 渲染时捕获异常: 不支持负索引。
这是模板脚本
{% for promotion in promotions%}
{% with promotion.appointment_set.all as appointments %}
{% with appointments|first as first_ap %}
{{ first_ap.date|date }}
{% endwith %}
{% with appointments|last as last_ap %}
{{ last_ap.date|date }}
{% endwith %}
{% endwith %}
{% endfor %}
我在这里做错了什么?
答案 0 :(得分:5)
在将查询集提供给模板之前将其转换为列表也可以获得您想去的位置:
return render_to_response(template, {
appointments: list(Appointments.objects.all())
})
由于我正在使用整个列表,我做了类似的事情(可能会有改进):
{% for ap in appointments %}
{% ifequal ap appointments|last %}
ap.date
{% endifequal %}
{% endfor %}
对象属性仍然有效。例如:ap.user.full_name
答案 1 :(得分:3)
last
标记的工作方式是使用负索引格式切片列表以获取最后一项:collection[-1]
。但是,正如错误消息指出的那样,查询集不支持负索引。
解决此问题的最简单方法可能是在Promotion
模型上创建一个新方法以返回上次约会:
class Promotion(models.Model):
... fields, etc ...
def get_last_appointment(self):
try:
return self.appointment_set.all().order_by('-date')[0]
except IndexError:
pass
并从模板中调用它:
{{ promotion.get_last_appointment.date|date }}
答案 2 :(得分:3)
问题的原因是@Daniel pointed out:查询集不支持负索引。他的解决方案值得探索。
解决此问题的另一种方法是添加一个可用于列表和查询集的自定义过滤器。类似的东西:
@register.filter
def custom_last(value):
last = None
try:
last = value[-1]
except AssertionError:
try:
last = value.reverse()[0]
except IndexError:
pass
return last
在模板中:
{% with appointments|custom_last as last_ap %}