Solution details

Every form instance has an attribute called fields, which is a dictionary that holds all the form fields. This can be modified at runtime. Adding or changing the fields can be done during form initialization itself.

For example, if we need to add a checkbox to a user-details form only if a keyword argument named "upgrade" is true upon form initialization, then we can implement it as follows:

class PersonDetailsForm(forms.Form): 
    name = forms.CharField(max_length=100) 
    age = forms.IntegerField() 
 
    def __init__(self, *args, **kwargs): 
        upgrade = kwargs.pop("upgrade", False) 
        super().__init__(*args, **kwargs) 
 
        # Show first class option? 
        if upgrade: 
            self.fields["first_class"] = forms.BooleanField( 
                label="Fly First Class?") 

Now, we just need to pass the PersonDetailsForm(upgrade=True) keyword argument to make an additional Boolean input field (a checkbox) appear.

A newly introduced keyword argument has to be removed or popped before we call super to avoid the unexpected keyword error.

If we use a FormView class for this example, then we need to pass the keyword argument by overriding the get_form_kwargs method of the View class, as shown in the following code:

class PersonDetailsEdit(generic.FormView): 
    ... 
 
    def get_form_kwargs(self): 
        kwargs = super().get_form_kwargs() 
        kwargs["upgrade"] = True 
        return kwargs 

This pattern can be used to change any attribute of a field at runtime, such as its widget or help text. It works for model forms as well.

In many cases, a seeming need for dynamic forms can be solved using Django formsets. They are used when a form needs to be repeated in a page. A typical use case for formsets is when designing a data-grid-like view to add elements row by row. This way, you do not need to create a dynamic form with an arbitrary number of rows; you just need to create a form for the row and create multiple rows using a formset_factory function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.219.217