Search code examples
pythondjangoformsdjango-formsdjango-formwizard

Django form wizard handling


I am having a bit of a problem understanding the django form wizard.

Mainly, I don't understand how to handle the form_list.

This is my view thus far:

class AddLocation(SessionWizardView):
    template_name = "dash/AddLocation.html"

    def processAddLocation(self, form_list, **kwargs):

    def done(self, form_list, **kwargs):
        processAddLocation(form_list)
        return redirect(reverse('location_manager'))

And here are my forms:

class regionForm(forms.Form):
    name = forms.CharField(max_length=255)


class locationForm(forms.Form):
    location_name = forms.CharField()
    street_address = forms.CharField()
    city = forms.CharField()
    zip_code = forms.CharField()

(yes each form is one page of the wizard)

And here is the model this form wizard should ultimately be saving as:

class Location(models.Model):
    region = models.ForeignKey(Region, blank=True, null=True)
    manager = models.ForeignKey(User, blank=True, null=True)
    name = models.CharField(max_length=255)
    street_address = models.TextField(blank=True)  # allowing this blank for the min.
    city = models.CharField(max_length=255, blank=True)
    zip_code = models.CharField(max_length=20, blank=True)
  1. Now how exactly do I go about handling the form_list?
  2. What exactly is the form_list returning?
  3. Why do I need a proccessAddLocation method and a done method (this was suggested to me but I can not seem to understand why).
  4. How do you save 2 forms to a specific model

Any pointers in the right direction will be very much appreciated.


Solution

  • The form list is simply a list of the valid forms that the user has completed. Creating a location from one form is the same as creating it from many. You just need to make sure you get the data from the correct form's cleaned_data dict.

    Your done method of your view will look something like this:

    def done(self, form_list, **kwargs):
        region_form, location_form = form_list
        location = Location(
            street_address=location_form.cleaned_data['street_address']
            # populate other fields here
            ...
        )
        location.save()
    
        return redirect(reverse('location_manager'))
    

    You need a done method because form wizards require it. You don't need a processAddLocation method, so I haven't included it in my answer. You can define this method and move the location creation code into it if you feel it makes the code easier to understand.

    In the case of the foreign keys e.g. region, you will have to transform the cleaned_data['region'] into a region object. You may have to add validation to your forms to make sure your user enters a valid region. A ModelChoiceField may be better for these foreign key fields.