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

时间:2011-10-01 03:56:36

标签: python django django-templates

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

{% 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(),但是我无法理解为什么这样做以及如何处理它在我的自定义模板标记内。

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

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

我找到了django-templateaddons{% counter %} tag,它在模板级别上工作,与嵌套循环无关。

答案 2 :(得分:0)

我有一种技术可以很好地限制嵌套循环中不需要任何自定义标记的行为。唯一的限制是您必须事先知道您尝试设置的上限。在我们的案例中,我们知道我们只希望显示来自任意数量的发布者的前六个图像库,以及每个发布者的图库。它严格来说是一个表示层限制,因此我们不希望特殊情况下的视图。主要的警告是,您必须在循环标记中包含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 %}