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



我试图使一个自定义模板标签,将增加一个变量。可以这样使用:

{% 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循环中使用计数器标记之前,这是可以正常工作的。count变量在循环内递增,但在循环外调用该变量时被重置为1。

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

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

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

我发现django-templateaddons库中有{% counter %}标签,它在模板级独立于嵌套循环。

我有一种技术,可以很好地限制嵌套循环中的行为,而不需要任何自定义标记。唯一的限制是你必须事先知道你要设置的上限。在我们的例子中,我们知道我们只想显示任意数量发布者中的前六个图片库,以及每个发布者的图片库。这是一个严格的表示层限制,所以我们不想对视图进行特殊处理。主要的警告是,在循环标记中必须有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 %}

最新更新