【问题标题】:In a forms of an inlineformset how can I know which are my default form fields and which are the ones added by Django?在 inlineformset 的表单中,我如何知道哪些是我的默认表单字段,哪些是 Django 添加的?
【发布时间】:2019-03-17 12:59:05
【问题描述】:

我有一个特定的表单集(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 添加另外两个字段,外键字段和删除字段。

因为我想对多个表单集使用相同的代码,在循环中我不请求field by name

我需要知道:

 {% for field in form %}{{ field }}{% endfor %}

我如何知道哪些是我的默认表单字段,哪些是 Django 添加的?

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    在使用表单实例时,您无法确定最初在类中或在实例化之后添加了哪些字段。

    不过,这里有一些方法可以防止那些您不想在结果表单集中呈现的字段。

    如果您可以访问表单的类...

    ...目前您需要“过滤”哪些字段可以包含此类表单的原始字段:

    >>> class MyForm(forms.Form):
    >>>    title = forms.CharField()
    
    >>> class_dict = vars(MyForm)
    
    >>> class_dict['declared_fields']
    
    OrderedDict([('title', <django.forms.fields.CharField at 0x7f496ce067d0>)])
    

    关于 *-DELETE 和 *-ORDER 字段

    在处理表单集时,您必须考虑到不仅 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 呢

    这是您可以在表格中解决的问题。如果您不希望显示 ForeignKey,可以在表单中的此类字段中使用 forms.HiddenInput 小部件。

    此外,如果您正在使用 ModelForms,您可以 select the fields to use 生成表单。

    结论

    有了这些信息,我希望您能够计划如何实现您对这些表单集的通用模板的要求。

    起点:

    1. 将can_delete 或/和start_order 作为False 传递给formset_factory。
    2. 为表单中的 ForeignKey 字段设置 forms.HiddenInput 小部件。
    3. 找到一种方法来获取表单类并使用vars 来找出 表单的原始字段。
    4. 如果您使用的是 ModelForms,请使用 fields 或 exclude 元配置来说明用于构建表单的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多