pythondjangodjango-formsdjango-formwizarddjango-formtools

(Django) Saving a Custom User Model in Django Form Wizard


I am having trouble creating a multi-step registration page for users. So far, I have a custom user model called Account to which I have added some fields that affect other things within my project. The model works fine when I just use a single-step registration form. However, once I transitioned to a multi-step registration form (with Django Form Wizard) and separated the basic registration (email, username, password) from the other fields, I started encountering some difficulty. Reading the Django Form Wizard documentation doesn't help much. I also want to note I am creating another model (which has my custom user model as a Foreign Key) upon registration. Here is my code:

forms.py

class RegisterForm1(UserCreationForm):
   email = forms.EmailField()

   class Meta:
      model = Account
      fields = ["username", "email", "password1", "password2", ]
      help_texts = {
        'username': None,
        'password1': None,
        'password2': None,
    }

    def __init__(self, *args, **kwargs):
        super(RegisterForm1, self).__init__(*args, **kwargs)
        self.fields['password1'].help_text = ''
        self.fields['password2'].help_text = ''

class RegisterForm2(forms.ModelForm):
    class Meta:
        model = Account
        fields = ["int_field", "char_field", ]

    def __init__(self, *args, **kwargs):
        super(RegisterForm2, self).__init__(*args, **kwargs)

views.py

class register_new(SessionWizardView):
template_name = "register/register.html"
form_list = [RegisterForm1, RegisterForm2]
def done(self, form_list, form_dict, **kwargs):
    form1 = RegisterForm1(self.request.POST)
    form2 = RegisterForm2(self.request.POST)
    if form1.is_valid() and form2.is_valid():   
        username = self.request.POST['username']
        email = self.request.POST['email']
        password = self.request.POST['password1']
        int_field = self.request.POST['int_field']
        char_field = self.request.POST['char_field']
        user = Account(username=username, email=email, password=password, int_field=int_field, char_field=char_field)
        user.save()
        ModelA.objects.create(user=user, classification="c")
        ModelA.objects.create(user=user, classification="h")
        ModelA.objects.create(user=user, classification="f")
        ModelA.objects.create(user=user, classification="e")
    return redirect('/')

This code does not even create a new user (I can see that nothing happens in my /admin). I know it doesn't have to do with my models since everything worked when I was using a simple single-step-form.

tl;dr I basically want to set up a multi-step registration form for a custom user model, while also creating a new model for the user upon registration.


Solution

  • First of all you don't need to validate the forms. According the docs when you get to the done function the forms are already validated.

    This can be removed:

    form1 = RegisterForm1(self.request.POST)
    form2 = RegisterForm2(self.request.POST)
    
    Because all the forms are available in the form_list
    

    In the docs one of the ways to get the form data is as follows:

    form_data = {
     'form_data': [form.cleaned_data for form in form_list],
    }
    

    THe only thing you need to do afterwards is get the values from the form data and create the user obj.