如何在Django模板中将forloop.counter与字符串连接?

22 投票
3 回答
15438 浏览
提问于 2025-04-16 16:05

我现在正在尝试这样连接字符串:

{% for choice in choice_dict %}
    {% if choice =='2' %}
        {% with "mod"|add:forloop.counter|add:".html" as template %}
            {% include template %}
        {% endwith %}                   
    {% endif %}
{% endfor %}    

但是不知为什么,我只得到了“mod.html”,而没有得到循环计数的数字。有没有人知道这是怎么回事,我该怎么解决这个问题呢?非常感谢!

3 个回答

3

试着使用“with”这个块

{% for choice in choice_dict %}
    {% if choice =='2' %}
       {% include "mod"|add:forloop.counter|add:".html" %}                   
    {% endif %}
{% endfor %} 
3

你可能不想在模板里这样做,这更像是视图层的工作:在循环中使用if语句。

chosen_templates=[]
for choice in choice_dict:
  if choice =='2':
    {% with "mod"|add:forloop.counter|add:".html" as template %}
    template_name = "mod%i.html" %index
    chosen_templates.append(template_name)

然后把chosen_templates传递给你的模板,这样你只需要处理

{% for template in chosen_templates %}
  {% load template %}
{% endfor %}

另外,我不太明白你为什么要用字典来选择一个字典里没有的数字对应的模板。for key,value in dict.items()可能是你想要的方式。

51

你的问题是,forloop.counter是一个整数,而你使用的add模板过滤器在处理字符串或整数时会正常工作,但如果混合使用就不行了。

解决这个问题的一种方法是:

{% for x in some_list %}
    {% with y=forloop.counter|stringformat:"s" %}
    {% with template="mod"|add:y|add:".html" %}
        <p>{{ template }}</p>
    {% endwith %}
    {% endwith %}
{% endfor %}

这样做的结果是:

<p>mod1.html</p>
<p>mod2.html</p>
<p>mod3.html</p>
<p>mod4.html</p>
<p>mod5.html</p>
<p>mod6.html</p>
...

第二个标签是必须的,因为stringformat标签会自动加上一个%符号。为了绕过这个问题,你可以创建一个自定义过滤器。我用的类似于这个:

http://djangosnippets.org/snippets/393/

把这个代码片段保存为 some_app/templatetags/some_name.py

from django import template

register = template.Library()

def format(value, arg):
    """
    Alters default filter "stringformat" to not add the % at the front,
    so the variable can be placed anywhere in the string.
    """
    try:
        if value:
            return (unicode(arg)) % value
        else:
            return u''
    except (ValueError, TypeError):
        return u''
register.filter('format', format)

在模板中:

{% load some_name.py %}

{% for x in some_list %}
    {% with template=forloop.counter|format:"mod%s.html" %}
        <p>{{ template }}</p>
    {% endwith %}
{% endfor %}

撰写回答