Django模板切片 - 逆转顺序

The*_*ing 10 python django django-templates

感谢我从另一个问题中得到的非常有用的提示,我可以通过在模板中切片来限制列表中的值的数量:

{% for comment in thread.comment_set.all|slice:":3" %}
Run Code Online (Sandbox Code Playgroud)

现在我想得到我的评论的最后3个结果,所以我想一个简单的":-3"或"-3"就可以了,唉:

Caught an exception while rendering: Negative indexing is not supported.
Run Code Online (Sandbox Code Playgroud)

还使用:

{% for comment in thread.comment_set.all|slice:":3" reversed %}
Run Code Online (Sandbox Code Playgroud)

不行,因为如果我有5条评论,而不是1,2,3则显示3,2,1顺序中的前三条.

有什么方法可以显示帖子的最后3条评论而无需进入我的数据库吗?我希望能够纯粹使用模板系统来做到这一点.

{% for comment in thread.comment_set.all|dictsortreversed:"created"|slice:"3" %}
Run Code Online (Sandbox Code Playgroud)

由于我的表具有创建的时间戳,显示最后三个.

Jar*_*die 13

Django的数据库查询是懒惰地评估的,因此结果thread.comment_set.all是QuerySet,而不是列表.QuerySet支持许多类似列表的函数,但不支持负片,因此索引错误不是来自模板过滤器本身.(如果您很好奇,QuerySet对象上的切片会被转换为limitSQL语句中的子句,这就是您不能使用负数的原因).

一般来说,Django鼓励严格的模板和模型分离; 该views.py模块是你做的,需要数据库模型和查询集方法的知识,你的模型数据转换成简单变量和结构为模板任何工作的胶水.

从模板运行模型的相关查询不是您通常在Django模板中看到的,并且有充分的理由.现在,从comment_set中切割最后三个元素似乎非常简单.但请记住,数据库不会以任何保证顺序返回结果.这意味着,除了切片之外,您现在还需要添加一个order_by子句; 根本没有办法在模板中表达这一点,也不应该存在.最好将视图视为模型和模板之间的转换,并让这些面向数据库的工作在那里完成,而不是嵌入在HTML中.

在这种情况下,我建议您从视图中将有序切片传递给模板:

# take first three sorted descending
comments = thread.comment_set.order_by('-something')[:3]

context = Context({'comments':comments})
return HttpResponse(tmplt.render(context))
Run Code Online (Sandbox Code Playgroud)

如果必须在模板中进行切片,并且实际上不关心对结果进行排序,请将列表传递给模板.该slice过滤器会很乐意做负切片:

comments = list(thread.comment_set.all())
context = Context('comments':comments)
Run Code Online (Sandbox Code Playgroud)

在模板中:

{% for comment in comments|slice:"-3:" %}
Run Code Online (Sandbox Code Playgroud)


cza*_*aic 10

我没有看到过于经常使用的dictsortreversed过滤器,根据文档,它需要一个键来排序

{% for comment in thread.comment_set.all|dictsortreversed:"name"|slice:"3" %}
Run Code Online (Sandbox Code Playgroud)