Django - 一个计数器模板标签,即使使用嵌套的 for 标签也能很好地工作

Posted

技术标签:

【中文标题】Django - 一个计数器模板标签,即使使用嵌套的 for 标签也能很好地工作【英文标题】:Django - A counter template tag that works well even with nested for tag 【发布时间】:2011-11-28 21:41:23 【问题描述】:

我正在尝试制作一个自定义模板标签来增加一个变量。可以这样使用:

% for fruit in basket %
    if fruit.is_apple %% count apples %% endif %
% endfor %
<p>There are  apples  apples in your basket</p>

我想出了这个:

#project/app/templatetags/counter.py

class CounterNode(template.Node):
    def __init__(self, varname):
        self.varname = varname

    def render(self, context):
        if self.varname in context:
            context[self.varname] += 1
        else:
            context[self.varname] = 1
        return ''


@register.tag
def counter(parser, token):
    try:
        tag_name, args = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError(
            "'counter' node requires a variable name.")
    return CounterNode(args)

在您尝试在 for 循环中使用 counter 标记之前,这可以正常工作。 count 变量在循环内递增,但在循环外调用该变量时重置为 1。

这与 template.defaulttags.ForNode 类的 render() 方法有关,该方法最后调用 context.pop(),但我无法理解为什么会这样做以及如何处理在我的自定义模板标签中。

所以问题是:即使通过 for 循环,我怎样才能让我的计数器标签增加?

【问题讨论】:

您需要模板中的计算吗? 使用什么标签并不重要。问题是在 forloop 中设置的任何变量在 forloop 之外都不可用。 仍有一些情况需要通过所有模板进行简单的计数器。例如。我有一个问题 - 在生成 Kindle 电子书导航控制文件 (NCX) 文件时,我需要用于顺序 PlayOrder 属性的计数器。由于文件的某些内容是在 % for % 循环中生成的,因此我无法使用它,否则它非常有用,模板标签。 【参考方案1】:

废弃计数标签并创建一个计算水果的模型方法或通过视图方法传递计数。模板并非真正用于业务逻辑,即使它像计数一样简单。

【讨论】:

【参考方案2】:

我发现django-templateaddons 库具有% counter % tag,它在独立于嵌套循环的模板级别上工作。

【讨论】:

【参考方案3】:

我有一种技术可以很好地限制不需要任何自定义标签的嵌套循环中的行为。唯一的限制是您必须事先知道您要设置的上限。在我们的例子中,我们知道我们只想显示任意数量的出版商中的前六个图像画廊,以及每个出版商的画廊。这是严格的表示层限制,所以我们不想对视图进行特殊处理。主要的警告是循环标签中必须有 n+1 个值,以确保没有重复。是的,我知道我在声明之前指的是“mycycle”,但是由于您不能真正在 Django 模板语言中声明变量,我想我可以原谅;效果很好。

% for pubs in sortedpubs %
    % for gallery in pubs.publisher.galleries.all %
        # Code to count inside nested loops... #
        # Uses "cycle" from the next line to count up to 6, then stop rendering #
        % if mycycle < 6 % 
            <!-- % cycle 1 2 3 4 5 6 7 as mycycle % -->
            # ...Render Stuff here... #
        % endif %
    % endfor % 
% endfor %

【讨论】:

以上是关于Django - 一个计数器模板标签,即使使用嵌套的 for 标签也能很好地工作的主要内容,如果未能解决你的问题,请参考以下文章

Django 在模板标签中过滤和计数

Django模板:获取嵌套循环的总迭代次数

Django 1.10 模板在其父级之外呈现嵌套的 HTML 标签

Django 从嵌套应用程序加载模板标签无法正常工作

django 模板中{%for%}的使用

Django 模板未正确格式化 <pre> 标签