Django 模板 - 如何在给定索引号(由迭代器生成)的情况下访问表单(上下文)中的表单
Django template - how to access form in forms (context) given an index number (generated by an iterator)
我有两种形式 - 源形式和结果形式。
Forms.py
class SourceForm(forms.Form):
some_source_field = forms.forms.CharField(...)
class ResultForm(forms.Form):
some_result_field = forms.forms.CharField(...)
我的视图使用 formset_factory
来呈现每个实例的两个实例,并将其传递给模板,其中包含与要呈现的表单数量相匹配的数字范围。
Views.py
class MyView(Vew):
def get(self, request):
forms_to_render = 2
SourceFormSet = formset_factory(SourceForm, extra=forms_to_render)
ResultFormSet = formset_factory(ResultForm, extra=forms_to_render)
context = {
'source_forms': SourceFormSet,
'result_forms': ResultFormSet,
'init': range(0, forms_to_render),
}
在我的模板中,我想为给定范围内的每个数字(在本例中为 2)生成一个容器,其中包含 source_form 和 result_form,如下所示。
template.html
{% for i in init %}
<div class="container-fluid" id="primary_container_{{ i }}">
{{ source_forms.i }}
{{ result_forms.i }}
</div>
{% endfor %}
背景:我有一个 javascript 队列,它一次取消隐藏一个 primary_container
进行处理;当用户处理队列中的下一个表单集时,我隐藏了 "just-processed" 容器并在后台填充它。目的是最小化表单填充时的等待时间。
如果我硬编码 0 或 1 的索引值,表单将呈现。
{{ source_forms.0 }} <!-- works fine -->
{{ source_forms.1 }} <!-- works fine -->
然而,这不起作用
{% for i in init %}
{{ source_forms.i }} <!-- doesn't render form -->
{% endfor %}
我想也许 i
不再是正确的数据类型,所以我尝试了这个,它也不起作用
{% for i in init %}
{% with forloop.counter0 as x %}
{{ source_forms.x }} <!-- doesn't render form -->
{% endwith %}
{% endfor %}
我通过这样做让它工作:
{% for i in init %}
{% for form in source_forms %}
{% if forloop.counter0 == i %}
{{ form }} <!-- renders form -->
{% endif %}
{% endfor %}
{% endfor %}
但是,在给定索引 i
的情况下,是否有更简单的方法在 forms
中获得正确的 form
?
Django 模板引擎设计 不允许您进行索引。
答案是使用 custom tag 来做索引(或者使用 Jinja 模板引擎,如果这是唯一需要解决的问题的话,这有点像大锤)。这是我之前写的,用于索引类似 dict 的实体。
from django import template
register = template.Library()
@register.filter
def lookup( d, key):
""" filter: d is dict-like. return d[key] with '' as default using get method """
return d.get( key, '')
用法:{{ dict_thing|lookup:key }}
在你的情况下,我希望以下内容能起作用:
@register.filter
def index( lst, index):
return lst[index]
用法:{{ source_forms|index:x }}
注意:模板中 |
或 :
周围不允许有空格
我过去使用的另一种方法是将上下文中的生成器函数 ( yield result
) 传递给模板,然后您可以使用 {% for x in generator %}
在模板中迭代我认为Python 的 zip
可能就是您所需要的:
return render( ... context={
'formpairs': zip( SourceFormSet, ResultFormSet), ...
})
并在模板中
{% for pair in formpairs %}
<div class="container-fluid" id="primary_container_{{ forloop.counter }}">
{{ pair.0 }}
{{ pair.1 }}
</div>
{% endfor %}
我有两种形式 - 源形式和结果形式。
Forms.py
class SourceForm(forms.Form):
some_source_field = forms.forms.CharField(...)
class ResultForm(forms.Form):
some_result_field = forms.forms.CharField(...)
我的视图使用 formset_factory
来呈现每个实例的两个实例,并将其传递给模板,其中包含与要呈现的表单数量相匹配的数字范围。
Views.py
class MyView(Vew):
def get(self, request):
forms_to_render = 2
SourceFormSet = formset_factory(SourceForm, extra=forms_to_render)
ResultFormSet = formset_factory(ResultForm, extra=forms_to_render)
context = {
'source_forms': SourceFormSet,
'result_forms': ResultFormSet,
'init': range(0, forms_to_render),
}
在我的模板中,我想为给定范围内的每个数字(在本例中为 2)生成一个容器,其中包含 source_form 和 result_form,如下所示。
template.html
{% for i in init %}
<div class="container-fluid" id="primary_container_{{ i }}">
{{ source_forms.i }}
{{ result_forms.i }}
</div>
{% endfor %}
背景:我有一个 javascript 队列,它一次取消隐藏一个 primary_container
进行处理;当用户处理队列中的下一个表单集时,我隐藏了 "just-processed" 容器并在后台填充它。目的是最小化表单填充时的等待时间。
如果我硬编码 0 或 1 的索引值,表单将呈现。
{{ source_forms.0 }} <!-- works fine -->
{{ source_forms.1 }} <!-- works fine -->
然而,这不起作用
{% for i in init %}
{{ source_forms.i }} <!-- doesn't render form -->
{% endfor %}
我想也许 i
不再是正确的数据类型,所以我尝试了这个,它也不起作用
{% for i in init %}
{% with forloop.counter0 as x %}
{{ source_forms.x }} <!-- doesn't render form -->
{% endwith %}
{% endfor %}
我通过这样做让它工作:
{% for i in init %}
{% for form in source_forms %}
{% if forloop.counter0 == i %}
{{ form }} <!-- renders form -->
{% endif %}
{% endfor %}
{% endfor %}
但是,在给定索引 i
的情况下,是否有更简单的方法在 forms
中获得正确的 form
?
Django 模板引擎设计 不允许您进行索引。
答案是使用 custom tag 来做索引(或者使用 Jinja 模板引擎,如果这是唯一需要解决的问题的话,这有点像大锤)。这是我之前写的,用于索引类似 dict 的实体。
from django import template
register = template.Library()
@register.filter
def lookup( d, key):
""" filter: d is dict-like. return d[key] with '' as default using get method """
return d.get( key, '')
用法:{{ dict_thing|lookup:key }}
在你的情况下,我希望以下内容能起作用:
@register.filter
def index( lst, index):
return lst[index]
用法:{{ source_forms|index:x }}
注意:模板中 |
或 :
周围不允许有空格
我过去使用的另一种方法是将上下文中的生成器函数 ( yield result
) 传递给模板,然后您可以使用 {% for x in generator %}
在模板中迭代我认为Python 的 zip
可能就是您所需要的:
return render( ... context={
'formpairs': zip( SourceFormSet, ResultFormSet), ...
})
并在模板中
{% for pair in formpairs %}
<div class="container-fluid" id="primary_container_{{ forloop.counter }}">
{{ pair.0 }}
{{ pair.1 }}
</div>
{% endfor %}