DEV Community

Daniel Feldroy
Daniel Feldroy

Posted on • Edited on

20 2

Customizing Django Allauth Signup Forms

Sometimes you want to modify Django signup forms to include more data fields. In this tutorial, I have a fictional app called "SpyBook", a social network for secret operatives. At launch there are only two types of users, "Spy" and "Driver". Users need to be able to choose which one they are.

Our example will build off code from my Cookiecutter Django project, but should be portable to any project using Django Allauth.

Step 1: Tell Django-Allauth to Use A Customized Signup Form

At the bottom of config/settings/base.py, past in the following code snippet:

# Control the forms that django-allauth uses
ACCOUNT_FORMS = {
    "login": "allauth.account.forms.LoginForm",
    "add_email": "allauth.account.forms.AddEmailForm",
    "change_password": "allauth.account.forms.ChangePasswordForm",
    "set_password": "allauth.account.forms.SetPasswordForm",
    "reset_password": "allauth.account.forms.ResetPasswordForm",
    "reset_password_from_key": "allauth.account.forms.ResetPasswordKeyForm",
    "disconnect": "allauth.socialaccount.forms.DisconnectForm",
    # Use our custom signup form
    "signup": "spybook.users.forms.SpyBookSignupForm",
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Import Django Forms

In <yourprojectname>/users/forms.py, Cookiecutter Django imports django.contrib.auth.forms as forms. This is a namespace problem since typically django.forms is normally imported as plain forms. To address that, let's just import django.forms under a different namespace:

# Importing django.forms under a special namespace because of my old mistake
from django import forms as d_forms
Enter fullscreen mode Exit fullscreen mode

Step 3: Import django-allauth's SignUp Form

Right under that forms import, get the SignUpForm:

from allauth.account.forms import SignupForm
Enter fullscreen mode Exit fullscreen mode

Step 4: Write Our Custom SignUp Form

Rather than write out a long explanation, I'll just comment every line of code.

# SpyBookSignupForm inherits from django-allauth's SignupForm
class SpyBookSignupForm(SignupForm):

    # Specify a choice field that matches the choice field on our user model
    type = d_forms.ChoiceField(choices=[("SPY", "Spy"), ("DRIVER", "Driver")])

    # Override the init method
    def __init__(self, *args, **kwargs):
        # Call the init of the parent class
        super().__init__(*args, **kwargs)
        # Remove autofocus because it is in the wrong place
        del self.fields["username"].widget.attrs["autofocus"]

    # Put in custom signup logic
    def custom_signup(self, request, user):
        # Set the user's type from the form reponse
        user.type = self.cleaned_data["type"]
        # Save the user's type to their database record
        user.save()
Enter fullscreen mode Exit fullscreen mode

I wrote this out on my live stream, which you can watch on my youtube and twitch channels. I'll also be putting together a short video presentation of how this works. Of course, the code for this can be found on GitHub.

If you want to learn all kinds of advanced tricks and tips, take a look at my ice-cream themed book and course on Django Best Practices.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (1)

Collapse
 
auxfuse profile image

Now that the default signup form has been extended, how can you then add the "spy" dropdown to the admin panel?

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay