How To Keep Your Custom Form Fields DRY

Article by Wayne Fagan. Published on 7 Sep, 2020.

When building a custom form which yields a group of incremental fields several times over, we often manually create each group like the following:

class ExampleForm(forms.ModelForm):

    first_name_1 = forms.CharField(required=False)
    last_name_1 = forms.CharField(required=False)

    ...

    first_name_10 = forms.CharField(required=False)
    last_name_10 = forms.CharField(required=False)

Now imagine having to do this many times over for a large group of fields, as you can imagine it would become very unwieldy and rather ugly, and most certainly would not be DRY.

I recently had to resolve this same issue for a project I was working on, my solution was to use a built in Python function called locals(). I was able to refactor my code so that I could adhere to the DRY principle and delete many lines of unnecessary lines of code (🤩).

The following is an example of how I refactored my code:

class ExampleForm(forms.ModelForm):

    for count in range(0, 10):
        locals()['first_name_' + str(count)] = forms.CharField(required=False)        
        locals()['last_name_' + str(count)] = forms.CharField(required=False)

As you can see I used locals() to dynamically create the variable names on each pass of the iteration. In this rather contrived example, the form would yield 10 groups of form fields with less code.

Rest assured that you can continue to reference the form fields as you would normally, in the form itself, views, templates, etc.

There is probably an even more succinct way!