Build a Custom User Registration Form in Django

Django framework comes with a UserCreationForm form that helps in creating user accounts quickly. By default, registration requires users to enter username, password and password confirmation.

old_regis.png That's cool! This is all written by a built-in class that is inherited from ModelForm class. But with each user being registered, there are also other attributes like first name, last name, email address for the model. What if we wanted to have user's names or email addresses to be specified? Could it be modified? Absolutely.

Let us take up an example and build a registration form to have first name, last name and email.

Let's start!!! Create a new file forms.py in the app's folder to build our very own custom registration form. Import forms, User model and UserCreationForm into the forms.py file.

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

class RegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = [
            'username',
            'first_name',
            'last_name',   
            'email'
        ]
         help_texts = {
            'username': None       
        }
        def save(self, commit=True):
            user = super(RegistrationForm, self.save(commit=False))
            # don't save since we dont have other fields just yet.
            user.first_name = self.cleaned_data['first_name']
            user.last_name = self.cleaned_data['last_name']
            user.email = self.cleaned_data['email']

            if commit:
                user.save()

            return user

In this form, we make the email as a necessary field while first_name and last_name as optional cleaned_data attribute makes sure that the user's input is valid and makes sure it's good to be stored in our database. Using help_texts, we can modify the validations for user's fields. Here let's overwrite the username to None. This avoid showing text below the username form. After running the save method, Django runs the SQL on our database to store user's data

The next step is to set up our views.py file.

from django.shortcuts import render, redirect
# import login
from django.contrib.auth import login
# from django.contrib.auth.forms import UserCreationForm
from .forms import RegistrationForm
#our custom form

def signUp(request):
    if request.method=="POST":
        form = RegistrationForm(request.POST)

        if form.is_valid():
            user = form.save()
            login(request,user)


            return redirect('/')

    else:
        form = RegistrationForm()

    return render(request,'core/signup.html', {'form':form})

The function first checks if the request is a POST(user has clicked submit button) or a GET(access information). If its a POST request, we access user's data using request.POST. If all user's input is valid and conditions are met, form's data is saved into the database. If the request is GET, an empty form is rendered as shown in the else block.

Now, let's move to the final stretch of task. Displaying the form. I've created a signup.html to display the form which inherits from base.html I've used bulma for extra styling and css.

<div class="container">
    <div class="columns">
        <div class="column is-12">
            <h1 class="title">Registration</h1>
        </div>
    </div>


            <div class="columns">
                <div class="column is-12">
            <form action="." method="POST">
                {% csrf_token %}

                {{ form.as_p }} <!--gives good styling -->

                <div class="field">
                    <div class="control">
                        <button class="button is-success">
                            Submit
                        </button>
                    </div>
                </div>
            </form>
        </div>
    </div>

Kudos, it's done!! Let's test this out.

batman.png

After clicking submit, we must have a record for our new user Batman :D

batmandb.png

It's working!! We have successfully created our own registration form by inheriting UserCreationForm provided by Django. This way we can optimize we own forms with different validations depending on the requirement.

Thanks for your time, please share your thoughts and suggestions in the comments. Cheers.