如何删除Django内联formset中“额外”表单上的“删除”复选框

时间:2018-03-22 10:29:22

标签: django inline-formset

我在Django中使用内联表单集,并为每个显示一个“额外”表单的项目添加另一个对象。

现有对象的表单有“删除”复选框,用于删除该对象,这是有意义的。

但是“额外”形式也有这些“删除”复选框......这没有任何意义,因为没有什么可以删除。 Django管理员中的内联表单不会显示“额外”表单的这些“删除”复选框。

如何在“额外”内联表单中删除这些复选框?

我的模板的内联formset部分是这样的(simplified, full version on GitHub):

{% for bookimage_form in form.forms %}
  {% for hidden_field in bookimage_form.hidden_fields %}
    {{ hidden_field.errors }}
  {% endfor %}

  {{ bookimage_form.as_table }}
{% endfor %}

这是“删除”复选框,似乎是多余的:

example screenshot

5 个答案:

答案 0 :(得分:3)

您可以使用InlineModelAdmin类的can_delete设置(TabularInline继承自InlineModelAdmin):

class BookImageInline(admin.TabularInline):
    model = BookImage
    extra = 1
    can_delete = False

答案 1 :(得分:1)

这是在遍历表单时到达模板的一种方法:

{% if bookimage_form.instance.pk %}
  <small><b>{{ bookimage_form.DELETE.label_tag }}</b></small><br>
  {{ bookimage_form.DELETE}}
{% else %}
{% endif %}

但是,您将无法使用我不认为的as_table()方法。您必须在表单中表达所有其他字段。

还有另一件事,您可以在初始化表单之后但在进入上下文之前进行尝试:

for f in form.forms: 
    if not f.instance.pk: 
        f.fields['DELETE'] = None 

不确定该如何在表格中显示出来,但您也许可以对此想法有所了解。

答案 2 :(得分:0)

我的建议是在嵌套的for循环中渲染模板并添加以下内容:

 {% if forloop.parentloop.last and forloop.last%}
     not render form filds
 {% else %}
     render field
 {% endif %}

答案 3 :(得分:0)

更新 Django 3.2+ (link),您现在可以将 can_delete_extra 作为 False 传递给 formset_factory 或它扩展类以从额外表单中删除复选框

<块引用>

can_delete_extra Django 3.2 中的新功能。

BaseFormSet.can_delete_extra

默认值:真

设置 can_delete=True 时,指定 can_delete_extra=False 删除删除额外表单的选项。

对于Django 3.2以下版本且不想升级的人,请使用以下覆盖BaseFormSet的方法:

class CustomFormSetBase(BaseModelFormSet):
        
    def add_fields(self, form, index):
        super().add_fields(form, index)
        if 'DELETE' in form.fields and form.instance.pk: # check if have instance
            form.fields['DELETE'] = forms.BooleanField(
                label=_('Delete'),
                widget=forms.CheckboxInput(
                    attrs={
                        'class': 'form-check-input'
                    }
                ),
                required=False
            )
        else:
            form.fields.pop('DELETE', None)


YourFormSet = modelformset_factory(
                formset=CustomFormSetBase,
                can_delete=True,
                extra=2
            )

他们只花了 13 年的时间来添加这个 >。> https://code.djangoproject.com/ticket/9061

答案 4 :(得分:0)

我在 django 官方文档中找到了删除删除复选框的方法here

您只需要在 views.py 文件中添加 'can_delete=false' 作为 inlineformset_factory 的参数

inlineformset_factory(can_delete=false)