我有一个特定的formset(inlineformset),我想对默认设计进行一些自定义。
我通过这种方式循环:
{% for form in formset %}
<div class="ct-formset">
{% if form.errors %}<div>{{ form.errors }}</div>{% endif %}
{% for field in form %}{{ field }}{% endfor %}
{% endfor %}
对于每个表单,Django在外键字段和删除字段中添加另外两个字段。
因为我想对多个formset使用相同的代码,所以在循环中我不会通过field
请求name
我需要知道:
{% for field in form %}{{ field }}{% endfor %}
我怎么知道哪些是我的默认表单字段,哪些是Django添加的字段?
在处理表单实例时,您无法确定在类中或实例化后最初添加了哪些字段。
虽然,在这里你有一些方法可以防止那些你不希望在结果formset中呈现的字段。
...目前您需要“过滤”您可以使用此类表单的原始字段的字段:
>>> class MyForm(forms.Form):
>>> title = forms.CharField()
>>> class_dict = vars(MyForm)
>>> class_dict['declared_fields']
OrderedDict([('title', <django.forms.fields.CharField at 0x7f496ce067d0>)])
在处理formset时,你必须考虑到不仅Django可以为你的表单添加额外的字段,你也可以这样做。
首先,我们必须了解为什么这些领域存在。
*-DELETE
和*-ORDER
字段的情况只有在你使用它们时添加:
formset = formset_factory(..., can_delete=True, can_order=True)
Django使用BaseFormSet.add_fields来添加启用排序或删除所需的额外字段,您也可以使用它来添加自己的附加字段。
你可以在那里通过False
。
我进行了一个实验,以说明这可能具有的覆盖效果:
from django import forms
class MyForm(forms.Form):
title = forms.CharField()
class MyBaseFormSet(forms.BaseFormSet):
def add_fields(self, form, i):
# Avoiding FormSets using this to add additional fields
return form
# Create a form set with deletion and ordering enabled.
# pay attention to the argument: formset=MyBaseFormSet
MyFormSet = forms.formset_factory(MyForm, formset=MyBaseFormSet, can_delete=True, can_order=True)
fs = MyFormSet()
for form in fs:
print(form.as_table())
结果,没有将DELETE或ORDER字段添加到生成的表单中。
>>> <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
这是你可以在表格中解决的问题。如果您不希望显示ForeignKey
,则可以在表单中的这些字段中使用forms.HiddenInput
小部件。
此外,如果您正在使用ModelForms,您可以使用select the fields to use生成表单。
有了这些信息,我希望您能够计划如何实现您对这些表单集具有通用模板的要求。
起点:
can_delete
或/和start_order
作为False传递给formset_factory
。forms.HiddenInput
来查找表单的原始字段。fields
元配置以说明用于构建表单的字段。