1

Is it possible to change what fields are displayed in a ModelForm, dynamically?

I am trying to show only a small number of fields in a ModelForm when the user adds a new instance (of the Model) from the frontend (using an add form) but larger number of fields when the user edits an instance (using an edit form).

The Form class looks something like this:

class SchoolForm(ModelForm):

    class Meta:
        model = School
        #want to change the fields below dynamically depending on whether its an edit form or add form on the frontend
        fields = ['name', 'area', 'capacity', 'num_of_teachers']
        widgets = {
            'area': CheckboxSelectMultiple
        }
        labels = {
            'name': "Name of the School",
            'num_of_teachers': "Total number of teachers",
        }

Trying to avoid having two separate classes for add and edit since that doesnt seem DRYish. I found some SO posts with the same question for the admin page where we could override get_form() function but that does not apply here.

Also, this answer suggests using different classes as the normal way and using dynamic forms as an alternative. Perhaps dynamics forms is the way forward here but not entirely sure (I also have overridden __init__() and save() methods on the SchoolForm class).

Anupam
  • 14,950
  • 19
  • 67
  • 94
  • Not sure if creating the form dynamically was ideal here given custom methods of `__init()__` and `save()`. For now, I resorted to specifying _all_ the fields that I needed (for the _edit form_) in the above class .The _add form_ needs a subset of these so it just picks up what it needs. I thought that was the simplest way to do it. For those wanting to explore options, I found [this](https://stackoverflow.com/questions/297383/dynamically-update-modelforms-meta-class/297478#297478) and [this](http://bradmontgomery.blogspot.in/2009/04/dynamically-displaying-fields-in.html) post helpful – Anupam Jun 12 '17 at 06:40

1 Answers1

0

I'm not suere if is a correct way, but i use some method in class to add fields or delete-it. I used like this:

class someForm(forms.ModelForm):


    class Meta:
        model = Foo
        exclude = {"fieldn0","fieldn1"}

    def __init__(self, *args, **kwargs):
        super(someForm, self).__init__(*args, **kwargs)

        self.fields['foofield1'].widget.attrs.update({'class': 'form-control'})

        if self.instance.yourMethod() == "FooReturn":
            self.fields['city'].widget.attrs.update({'class': 'form-control'})
        else:
            if 'city' in self.fields: del self.fields['city']

Hope it helps.

Zartch
  • 945
  • 10
  • 25
  • Thanks @Zartch, looks like the above is updating or deleting an existing field. Is there a way to _add_ fields (which were not included in the fields list earlier but are in the model)? – Anupam May 22 '17 at 13:51
  • All the fields not excluded are shown in the form. if you have some fields you want to do-it dinamically, you must delete-it: del self.fields['field'] – Zartch May 22 '17 at 13:54