在 Django 表单模板中使用变量作为表单字段
Use variable as form fields in Django form template
<here all loading of static , template_filters, crispy_forms >
<form>
{% for i in artifact_length %}
{% with artifact_name="artifact"|artifact_name:forloop.counter0 %}
{{form.artifact_name|as_crispy_field}}
{% endwith %}
{%endfor%}
</form>
这是相关的模板代码。在这里,我想渲染名称为 artifact_0
、artifact_1
的表单字段。 with
中的变量 artifact_name
工作正常并返回预期的标识符 artifact_0
, artifact_1
,但我想将这些变量用作表单字段以呈现为 as_crispy_field
.
代码 {{form.artifact_name|as_crispy_field}}
不打印任何内容,因为它假定表单为名称为 artifact_name
的字段,但事实并非如此。相反,我想在这里使用变量的值。
forms.py
class Someform(forms.form):
def __init__(self, artifact_obj):
super().__init__()
count = 0
for artifact in artifact_obj:
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
count += 1
tags.py
@register.filter('artifact_name')
def get_artifact_name(artifact_prefix: str, counter: int):
print('method', 'prefix', artifact_prefix, 'counter', counter)
return f'{artifact_prefix}_{counter}'
正在创建可变长度表单。正如在 forms.py
中,表单字段是用 artifact_count
创建的,其中计数范围从 0 到 obj 的 len。
您不需要为此目的使用过滤器/模板标签等。最简单的解决方案是 loop over the form fields 渲染它们:
<form>
{% for field in form %}
{{ field|as_crispy_field }}
{%endfor%}
</form>
这将遍历表单中的所有字段。
如果您特别关心这些字段的顺序,您可以调用表格 order_fields
method:
class Someform(forms.form):
def __init__(self, artifact_obj, *args, **kwargs):
super().__init__(*args, **kwargs)
for count, artifact in enumerate(artifact_obj):
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
self.order_fields(["field_1", "field_2", ...] + [f"artifact_{i}" for i, _ in enumerate(artifact_obj)] + [..., "field_n"])
如果您特别想单独呈现其他字段,您可以在您的表单中添加一个方法,使您可以循环遍历这些字段:
class Someform(forms.form):
def __init__(self, artifact_obj, *args, **kwargs):
super().__init__(*args, **kwargs)
for count, artifact in enumerate(artifact_obj):
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
self.artifact_length = len(artifact_obj)
def artifact_fields(self):
return [self[f'artifact_{i}'] for i in range(self.artifact_length)]
然后在模板中循环这些:
<form>
{% for field in form.artifact_fields %}
{{ field|as_crispy_field }}
{%endfor%}
</form>
<here all loading of static , template_filters, crispy_forms >
<form>
{% for i in artifact_length %}
{% with artifact_name="artifact"|artifact_name:forloop.counter0 %}
{{form.artifact_name|as_crispy_field}}
{% endwith %}
{%endfor%}
</form>
这是相关的模板代码。在这里,我想渲染名称为 artifact_0
、artifact_1
的表单字段。 with
中的变量 artifact_name
工作正常并返回预期的标识符 artifact_0
, artifact_1
,但我想将这些变量用作表单字段以呈现为 as_crispy_field
.
代码 {{form.artifact_name|as_crispy_field}}
不打印任何内容,因为它假定表单为名称为 artifact_name
的字段,但事实并非如此。相反,我想在这里使用变量的值。
forms.py
class Someform(forms.form):
def __init__(self, artifact_obj):
super().__init__()
count = 0
for artifact in artifact_obj:
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
count += 1
tags.py
@register.filter('artifact_name')
def get_artifact_name(artifact_prefix: str, counter: int):
print('method', 'prefix', artifact_prefix, 'counter', counter)
return f'{artifact_prefix}_{counter}'
正在创建可变长度表单。正如在 forms.py
中,表单字段是用 artifact_count
创建的,其中计数范围从 0 到 obj 的 len。
您不需要为此目的使用过滤器/模板标签等。最简单的解决方案是 loop over the form fields 渲染它们:
<form>
{% for field in form %}
{{ field|as_crispy_field }}
{%endfor%}
</form>
这将遍历表单中的所有字段。
如果您特别关心这些字段的顺序,您可以调用表格 order_fields
method:
class Someform(forms.form):
def __init__(self, artifact_obj, *args, **kwargs):
super().__init__(*args, **kwargs)
for count, artifact in enumerate(artifact_obj):
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
self.order_fields(["field_1", "field_2", ...] + [f"artifact_{i}" for i, _ in enumerate(artifact_obj)] + [..., "field_n"])
如果您特别想单独呈现其他字段,您可以在您的表单中添加一个方法,使您可以循环遍历这些字段:
class Someform(forms.form):
def __init__(self, artifact_obj, *args, **kwargs):
super().__init__(*args, **kwargs)
for count, artifact in enumerate(artifact_obj):
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
self.artifact_length = len(artifact_obj)
def artifact_fields(self):
return [self[f'artifact_{i}'] for i in range(self.artifact_length)]
然后在模板中循环这些:
<form>
{% for field in form.artifact_fields %}
{{ field|as_crispy_field }}
{%endfor%}
</form>