Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove "Delete" checkbox on "extra" forms in Django inline formset

I'm using inline formsets in Django, and for each item showing one "extra" form, for adding another object.

The forms for existing objects have "Delete" checkboxes, for removing that object, which makes sense.

But also the "extra" forms have these "Delete" checkboxes... which makes no sense because there's nothing there to delete. Inline forms in the Django admin don't show these "Delete" checkboxes for "extra" forms.

How can I remove these checkboxes on the "extra" inline forms?

The inline formsets part of my template is something like this (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 %}

And here's the "Delete" checkbox that seems superfluous:

example screenshot

like image 335
Phil Gyford Avatar asked Mar 22 '18 10:03

Phil Gyford


2 Answers

You can use the can_delete setting of the InlineModelAdmin class (TabularInline inherits from InlineModelAdmin):

class BookImageInline(admin.TabularInline):
    model = BookImage
    extra = 1
    can_delete = False
like image 84
bonidjukic Avatar answered Sep 18 '22 07:09

bonidjukic


Update for Django 3.2+ (link), you can now pass in can_delete_extra as False to formset_factory or it extended classes to remove checkbox from extra forms

can_delete_extra New in Django 3.2.

BaseFormSet.can_delete_extra

Default: True

While setting can_delete=True, specifying can_delete_extra=False will remove the option to delete extra forms.

For anyone having Django version under 3.2 and do not wish to upgrade, please use the following method of overriding the 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
            )

only took them 13 years to add this >.> https://code.djangoproject.com/ticket/9061

like image 33
Linh Nguyen Avatar answered Sep 20 '22 07:09

Linh Nguyen