How to make sequential signup pages with Django allauth?

I currently have a single page signup form implemented with allauth

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    
    email = models.EmailField(_('Professional email address'), unique=True)
    username = models.CharField(_("User Name"), blank=False, max_length=255, unique=True)
    first_name = models.CharField(_("First Name"), null=True, max_length=255, default='')
    last_name = models.CharField(_("Last Name"), null=True, max_length=255, default='')
    country = CountryField(_("Country of Practice"), blank_label='(Country of Practice)', blank = False, default='GB')
    terms = models.BooleanField(verbose_name=_('I have read and agree to the terms and conditions'), default=False)

 def get_absolute_url(self):
        return reverse(
            "users:detail", kwargs={"username": self.username}
        )

    objects = UserManager()

And this is the forms.py

class UserCreationForm(forms.UserCreationForm):

    error_message = forms.UserCreationForm.error_messages.update(
        {"duplicate_username": _("This username has already been taken.")}
    )

    username = CharField(label='User Name',
                        widget=TextInput(attrs={'placeholder': 'User Name'}))

    class Meta(forms.UserCreationForm.Meta):
        model = User
        fields = ['username', 'email',  'first_name', 'last_name', 'password1', 'password2', 'terms']
        field_order = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2', 'terms']

    def clean_terms(self):
        is_filled = self.cleaned_data['terms']
        if not is_filled:
            raise forms.ValidationError('This field is required')
        return is_filled  
    
    def clean_username(self):
        username = self.cleaned_data["username"]
        if self.instance.username == username:
            return username
        try:
            User._default_manager.get(username=username)
        except User.DoesNotExist:
            return username
        raise ValidationError(
            self.error_messages["duplicate_username"]
        )

I would like however for the first sign up page to have a ‘next’ button at the bottom and then there would be a second page where the user input separate details (the data input here might vary based on the inputs in the first page). The Django ‘form tools’ form wizard seems well suite to this but I can’t work out how to integrate it with all auth

Any suggestions much appreciated

as a first step have a look on the templates in the github repo:

https://github.com/pennersr/django-allauth/tree/master/allauth/templates/
    account/
       base.html
       ...
       login.html
       ....
    openid/
    ...

you can check the original pages and modify/overwrite them by creating folders/files in your app templates folder:

    your_app/
        templates/
           your_app/              # this is the app templates standard folder
           account/               # this one is to overwrite allauth->account templates
               base.html
               login.html
               ...
           openid/
               ...

Then you can change the action taken when buttons are clicked and that way could hook in an intermediate view/page. Remains to clarify how eventually posted parameters are kept in the chain of pages.

You can use Django's FormWizard to implement a multi-page form for user sign up, and integrate it with Django AllAuth by subclassing FormWizard and customizing its behavior as necessary.

Here's a basic example to get you started:

from formtools.wizard.views import SessionWizardView
from allauth.account.forms import SignupForm


class UserSignupWizard(SessionWizardView):
    form_list = [SignupForm, UserCreationForm]

    def done(self, form_list, **kwargs):
        # Implement logic to save the form data to the database
        # ...
        return HttpResponseRedirect(reverse("success_url"))

In the example above, form_list is a list of forms that will be used in the wizard. In this case, you are using both the SignupForm provided by Django AllAuth and your custom UserCreationForm. The done method is called when all the forms in the wizard have been filled out and submitted. This is where you can implement logic to save the form data to the database, send email confirmations, etc.

Note that you may need to customize the forms or the UserSignupWizard class to fit your specific needs.

Back to Top