Python 为什么这是迭代多窗口小部件的子窗口小部件的正确方法?

Python 为什么这是迭代多窗口小部件的子窗口小部件的正确方法?,python,django,Python,Django,我试图在Django中使用一个多窗口小部件表单。我想为这个小部件使用一个自定义模板,其中包括我的子小部件的基本内置模板(两个简单的文本输入)。 我在这件事上被阻止了一段时间 为了包含两个TextInput子窗口小部件的模板,导入自己重写两个HTML输入标记的内置窗口小部件似乎更聪明。我花了很多时间试图理解为什么这不起作用: {%用于widget.subwidgets%} {%include subwidget.template_name%} {%endfor%} 使用该循环创建的HTML代码为

我试图在Django中使用一个多窗口小部件表单。我想为这个小部件使用一个自定义模板,其中包括我的子小部件的基本内置模板(两个简单的文本输入)。 我在这件事上被阻止了一段时间

为了包含两个TextInput子窗口小部件的模板,导入自己重写两个HTML输入标记的内置窗口小部件似乎更聪明。我花了很多时间试图理解为什么这不起作用:

{%用于widget.subwidgets%}
{%include subwidget.template_name%}
{%endfor%}
使用该循环创建的HTML代码为:


并且无法按预期工作:输入值无法正确压缩,字段都将设置为解压缩方法的回退值

相反地,由于没有自定义模板,我的多窗口小部件工作得非常出色,由Django自动呈现两个文本输入

然后我有了一个想法:看看内置的Django multiwidget HTML模板!令人惊讶的是,代码与我的非常相似:

{%用于widget.subwidgets%}
{%include widget.template_name%}
{%endfor%}
这将呈现以下HTML:


工作正常(即输入的值被正确传递和压缩/解压缩)。我相信这是由于独特的HTML ID

所以,在某种程度上,我找到了问题的答案。问题是我不明白为什么我的第一个版本的循环没有完全一样的工作!我对Python的理解在这里可能还不够充分,但第一个循环和第二个循环中的单词“subwidget”和“widget”似乎代表同一个对象:iterable widget.subwidgets的一项。因此,这两个循环的行为应该没有区别

为了验证这一点,我尝试了:

{%用于widget.subwidgets%}
{{subwidget}}
{%endfor%}
{widget.subwidgets%中的小部件的%s} {{widget}}
{%endfor%}
两个循环的输出相同:

{'name':'f_0','is_hidden':False,'required':False,'value':None,'attrs':{'label':'latitude','class':'','required':True,'id':'id_f_0','template_name':'django/forms/widgets/text.html','type':'text'}
{'name':'f_1','is_hidden':False,'required':False,'value':None,'attrs':{'label':'longitude','class':'required':True,'id':'id_f_1'},'template_name':'django/forms/widgets/text.html','type':'text}
{'name':'f_0','is_hidden':False,'required':False,'value':None,'attrs':{'label':'latitude','class':'required':True,'id':'id_f_0'},'template_name':'django/forms/widgets/text.html','type':'text}
{'name':'f_1','is_hidden':False,'required':False,'value':None,'attrs':{'label':'longitude','class':'required':True,'id':'id_f_1'},'template_name':'django/forms/widgets/text.html','type':'text}
但是由于某些原因,include标记在两个循环中的行为并不相同,尽管它似乎在两个循环中的同一个确切变量上使用,只是它的名称不同而已

为什么呢


(为了不让python文件变得更冗长,我没有在问题中包含python文件的代码,因为我认为不需要它来解决这个问题,但如果认为它有用,我很乐意添加它)

当您包含子小部件模板时,模板需要一个专门命名为“小部件”的对象可用于访问该子小部件属性的

例如,以下是内置输入小部件模板的来源:

<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>

希望这有帮助

当您包含子小部件模板时,该模板期望存在一个专门命名为“小部件”的对象,该对象可用于访问该子小部件的属性

例如,以下是内置输入小部件模板的来源:

<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
希望这有帮助