Search code examples
djangofieldhideformset

hiding can_delete field in a django formset


I have a formset that I created using formset_factory() with the can_delete option set to true

In my html template each form is displayed with the form.as_p function so I don't have access to each html element

the can delete field is displayed by the template as a check box and I would like to hide it.

I could render the form manually a modify the appropriate tag but since there is a lot of fields in that form that seems to be a lot of code just to hide an element

I could also use javascript or css on the client side as explained here

However I suspect there might be a neater way to do it.

I read in the doc that there is also a can_order field which is similar to can_delete and that can also be activated when creating a form set. This can_order field can be hidden by creating a formset class with the appropriate attribute :

from django.forms import BaseFormSet, formset_factory
from myapp.forms import ArticleForm
class BaseArticleFormSet(BaseFormSet):
    ordering_widget = HiddenInput

ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet, can_order=True)

I am wondering if it is possible to do something similar with the can_delete field. Something like :

can_delete_widget = HiddenInput

instead of

ordering_widget = HiddenInput

Am i completely wrong and javascript/css should be my friends in that situation ?


Solution

  • You can override the add_fields method of BaseFormSet like this. This will also work with Django 2.2 (ordering_widget was added in 3.0):

    class MyFormSetBase(BaseFormSet):
    
        def add_fields(self, form, index):
            """ hide ordering and deletion fields """
            super().add_fields(form, index)
            if 'ORDER' in form.fields:
                form.fields['ORDER'].widget = forms.HiddenInput()
            if 'DELETE' in form.fields:
                form.fields['DELETE'].widget = forms.HiddenInput()
    
    MyFormSet = formset_factory(MyForm, formset=MyFormSetBase, extra=1, can_delete=True, can_order=True)