Python 如何在Django模板语言中正确构造for循环

Python 如何在Django模板语言中正确构造for循环,python,django,for-loop,django-templates,Python,Django,For Loop,Django Templates,我在Django应用程序中有一个模板文件,它使用来自使用模板变量的相应视图的数据。在视图的上下文中(在呈现页面时返回),我有一个名为len_values的变量,它存储循环结束范围的值。我目前使用以下语法构造for循环: <ul class= 'list-group'> {% for i in range(0,len_values) %} <li class = 'list-group-item' > Artist:

我在Django应用程序中有一个模板文件,它使用来自使用模板变量的相应视图的数据。在视图的上下文中(在呈现页面时返回),我有一个名为len_values的变量,它存储循环结束范围的值。我目前使用以下语法构造for循环:

 <ul class= 'list-group'>
     {% for i in range(0,len_values) %}
         <li  class = 'list-group-item' >
             Artist: {{form_artistSelect}}
             Location: {{venues.i.city}}, {{venues.i.region}}
             Venue: {{venues.i.name}}
             Date: {{dates.i}}
             tickets status: {{ticket_statuses.i}}<br>
             <a href = {{ticket_urls.i}}> ticket link </a>
             {% if user.is_authenticated %}
                 <button id = 'invite' type='button' class= 'btn btn-info btn-lg' data-toggle = 'modal' data-target='#myModal' venue={{venues.i}} date={{dates.i}} ticket_url={{ticket_urls.i}} artist = {{form_artistSelect}}> Invite a friend </button>
                 <button id = 'save' type = 'button' class = 'btn btn-primary-outline'> Save Concert </button>
             {% endif %}
         </li>
     {% endfor %}
 </ul>
    {范围(0,len_值)%}
  • 艺术家:{{form_artistSelect}} 地点:{{场馆.城市},{{场馆.地区} 地点:{{VICENTES.i.name} 日期:{{dates.i} 票证状态:{{ticket\u statuses.i}}
    {%if user.u经过身份验证%} 邀请朋友 拯救音乐会 {%endif%}
  • {%endfor%}
当我尝试此代码时,我遇到了错误:
无法解析剩余部分:“(0,len_值)”来自“range(0,len_值)”

我已经看到,这似乎解决了一个类似的问题,但没有一个决定性的答案的基础上投票和提供的答案是旧的


用Django模板格式构造for循环的正确方法是什么?

正如文档清楚显示的那样,用Django的模板语言是无法做到这一点的。即使你让范围位工作,你的变量查找本身也不会工作:在
Vincements.i.city
中的
i
总是被解释为字面名称“i”

但无论如何,您都不想这样做:即使在原始Python中也不应该这样做。您永远不会在范围(len(某物))上迭代;总是重复事物本身。在这里也是如此:在您看来,您应该创建一个数据结构(例如,一个目录列表),其中包含按项目分组的城市、地区、日期、状态等,然后在模板中迭代:

data = [
    {'city': "City 1", "region": "Region 1", "date": date_1, ....},
    ...
]
模板:

data = [
    {'city': "City 1", "region": "Region 1", "date": date_1, ....},
    ...
]
{% for item in data %}
    Location: {{ item.city }}, {{ item.region }}
    ...
{% endfor %}

正如文档清楚地显示的那样,在Django的模板语言中无法实现这一点。即使你让范围位工作,你的变量查找本身也不会工作:在
Vincements.i.city
中的
i
总是被解释为字面名称“i”

但无论如何,您都不想这样做:即使在原始Python中也不应该这样做。您永远不会在范围(len(某物))上迭代;总是重复事物本身。在这里也是如此:在您看来,您应该创建一个数据结构(例如,一个目录列表),其中包含按项目分组的城市、地区、日期、状态等,然后在模板中迭代:

data = [
    {'city': "City 1", "region": "Region 1", "date": date_1, ....},
    ...
]
模板:

data = [
    {'city': "City 1", "region": "Region 1", "date": date_1, ....},
    ...
]
{% for item in data %}
    Location: {{ item.city }}, {{ item.region }}
    ...
{% endfor %}

Django模板的设计使其语法尽可能简单。其想法是,模板是由设计师而不是程序员实现的

在您的例子中,问题在于不能简单地在for标记中添加类似于range(0,len_值)的Python代码。标记需要迭代器,迭代器可以由过滤器处理,但不能由任意Python表达式处理

您有不同的选项来迭代给定的次数:

  • 最简单的方法是更改视图,因此不需要数组的len,而是将数组本身传递给模板(上下文中有范围(len_值),而不仅仅是len_值)
  • 您可以创建自己的模板标记,该标记可能与的内置标记类似,但应该是len,而不是迭代器
  • 您可以使用Jinja2,它在语法上与Django模板非常相似,但在模板语法上没有太多限制(不确定在这种情况下您的代码是否可以工作)
但在你的情况下,我认为问题是另一个,在观点方面。不要为场馆、日期、票证状态等使用不同的迭代器。所有迭代器都具有相同的长度,而应该只有一个迭代器包含所有信息

因此,与其有如下视图:

def my_view(request):
    context = {'venues': ['venue 1', 'venue 2', 'venue 3'],
               'dates': ['date 1', 'date 2', 'date 2'],
               'ticket_statuses': ['status 1', 'status 2', 'status 3']}
    render(request, 'my_template.html', context)
您应该有如下内容:

def my_view(request):
    context = {'tickets': [
                  {'venue': 'venue 1', 'date': 'date 1', 'status': 'status 1'},
                  {'venue': 'venue 2', 'date': 'date 2', 'status': 'status 2'},
                  {'venue': 'venue 3', 'date': 'date 3', 'status': 'status 3'}]}
    render(request, 'my_template.html', context)
然后,您的模板将非常简单:

<ul class= 'list-group'>
     {% for ticket in tickets  %}
         <li  class = 'list-group-item' >
             Artist: {{form_artistSelect}}
             Location: {{ticket.venue.city}}, {{ticket.venue.region}}
             Venue: {{ticket.venue.name}}
             Date: {{ticket.date}}
             tickets status: {{ticket.status}}<br>
             <a href = {{ticket.url}}> ticket link </a>
             {% if user.is_authenticated %}
                 <button id = 'invite' type='button' class= 'btn btn-info btn-lg' data-toggle = 'modal' data-target='#myModal' venue={{venues.i}} date={{dates.i}} ticket_url={{ticket_urls.i}} artist = {{form_artistSelect}}> Invite a friend </button>
                 <button id = 'save' type = 'button' class = 'btn btn-primary-outline'> Save Concert </button>
             {% endif %}
         </li>
     {% endfor %}
 </ul>
    {票证%中的票证%
  • 艺术家:{{form_artistSelect}} 地点:{{ticket.vention.city},{{{ticket.vention.region} 地点:{{ticket.vention.name} 日期:{{ticket.Date} 票证状态:{{ticket.status}}
    {%if user.u经过身份验证%} 邀请朋友 拯救音乐会 {%endif%}
  • {%endfor%}

Django模板的设计使其语法尽可能简单。其想法是,模板是由设计师而不是程序员实现的

在您的例子中,问题在于不能简单地在for标记中添加类似于range(0,len_值)的Python代码。标记需要迭代器,迭代器可以由过滤器处理,但不能由任意Python表达式处理

您有不同的选项来迭代给定的次数:

  • 最简单的方法是更改视图,因此不需要数组的len,而是将数组本身传递给模板(上下文中有范围(len_值),而不仅仅是len_值)
  • 您可以创建自己的模板标记,该标记可能与的内置标记类似,但应该是len,而不是迭代器
  • 您可以使用Jinja2,它在语法上与Django模板非常相似,但在模板语法上没有太多限制(不确定在这种情况下您的代码是否可以工作)
但在你的情况下,我认为问题是另一个,在观点方面。不要为场馆、日期、票证状态等使用不同的迭代器。所有迭代器都具有相同的长度,而应该只有一个迭代器包含所有信息

因此,与其有如下视图:

def my_view(request):
    context = {'venues': ['venue 1', 'venue 2', 'venue 3'],
               'dates': ['date 1', 'date 2', 'date 2'],
               'ticket_statuses': ['status 1', 'status 2', 'status 3']}
    render(request, 'my_template.html', context)
您应该有如下内容:

def my_view(request):
    context = {'tickets': [
                  {'venue': 'venue 1', 'date': 'date 1', 'status': 'status 1'},
                  {'venue': 'venue 2', 'date': 'date 2', 'status': 'status 2'},
                  {'venue': 'venue 3', 'date': 'date 3', 'status': 'status 3'}]}
    render(request, 'my_template.html', context)
然后,您的模板将非常简单:

<ul class= 'list-group'>
     {% for ticket in tickets  %}
         <li  class = 'list-group-item' >
             Artist: {{form_artistSelect}}
             Location: {{ticket.venue.city}}, {{ticket.venue.region}}
             Venue: {{ticket.venue.name}}
             Date: {{ticket.date}}
             tickets status: {{ticket.status}}<br>
             <a href = {{ticket.url}}> ticket link </a>
             {% if user.is_authenticated %}
                 <button id = 'invite' type='button' class= 'btn btn-info btn-lg' data-toggle = 'modal' data-target='#myModal' venue={{venues.i}} date={{dates.i}} ticket_url={{ticket_urls.i}} artist = {{form_artistSelect}}> Invite a friend </button>
                 <button id = 'save' type = 'button' class = 'btn btn-primary-outline'> Save Concert </button>
             {% endif %}
         </li>
     {% endfor %}
 </ul>