Search code examples
djangofieldmodelform

how to dynamically set visible fields of a django modelform?


I would like the visible fields of a ModelForm to be determined by the instance of the model class it is built upon. The ModelForm is built upon the model protocol which has a method (protocol.visiblefields())which returns an array of strings corresponding to the fields to be made visible.

forms.py

class ListForm(ModelForm):   

    class Meta():
        model = protocol

        fields = []

views.py

newProtocol = protocol()
form = ListForm(instance=newProtocol)

Solution

  • You have a couple of options to do this, one is mostly in the view and the other is in the form __init__.

    Option 1: Pop the fields after initializing the form. Although you would need to specify all fields in the form Meta and remove the ones you don't want in the view.

    newProtocol = protocol()
    form = ListForm(instance=newProtocol)
    visible_fields = newProtocol.visiblefields()
    for field in form.fields:
        if field not in visible_fields:
            form.fields.pop(field)
    

    Option 2: Overwrite the __init__ method and pass the fields in. We include all fields and remove the ones we don't want.

    forms.py

    class ListForm(ModelForm):   
    
        class Meta:
            model = protocol
            fields = '__all__'
    
        def __init__(self, *args, **kwargs):
            visible_fields = kwargs.pop('visible_fields')
            super(ListForm, self).__init__(*args, **kwargs)
            for field in self.fields:
                if field not in visible_fields:
                    self.fields.pop(field)
    

    views.py

    newProtocol = protocol()
    form = ListForm(instance=newProtocol, visible_fields=newProtocol.visiblefields())