I ran into a slightly tricky use case the other day wherein I needed to grab some data from an API, validate it against a Django ModelForm, and only show the form to the user if there are errors during the validation.
If the form is shown, the error messages from the validation should appear along with a pre-populated form (using the data from the API). Otherwise, the ModelForm should submit and be saved immediately, without any user interaction.
After digging through Django’s code it became clear that to accomplish this, I needed to override a couple methods of the generic class-based CreateView.
Here’s the code for the view…
As you can see, the first thing I’m doing is overriding get_form_kwargs so that it can take a new argument – data. This allows me to pass in the data pulled from the API to the form. Since I want the form to be saved immediately, without any user interaction, I set both the initial and data properties to the passed in data.
The get method is now a simple exercise in pinging the API for data, placing it into a dictionary the form can use, and calling form.is_valid() to see if the data passes the validation.
If it doesn’t, the form is rendered (complete with validation errors and pre-populated data) and the post method handles when the form is submitted by the user.