User Registration

In this article, you’ll learn how to create an app for user registration. Users can then create an account, login and write posts without using admin page.

How to create user registration page

1. Create users app

python manage.py startapp users

2. Add users app in settings.py

INSTALLED_APPS = [
    'blog.apps.BlogConfig',
    'users.apps.UsersConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

3. Create a form

In users directory, create form.py:

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

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

    # Configuration
    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

4. Create a register view

Access views.py in users directory:

from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm # Import the form we just created

def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST) 
        if form.is_valid():
            form.save() # Save user to Database
            username = form.cleaned_data.get('username') # Get the username that is submitted
            messages.success(request, f'Account created for {username}!') # Show sucess message when account is created
            return redirect('blog-home') # Redirect user to Homepage
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})

5. Create a register URL pattern in mysite/urls.py

from django.contrib import admin
from django.urls import path, include
from users import views as user_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
    path('register/', user_views.register, name ='register')
]

6. Update base.html

To show our message alert that we created in the users/views.py in step 4, we’ll need to update our blog/base.html.

In the main section, before {% block content %}{% endblock %}, add:

<div class="col-md-8">
    {% if messages %}
        {% for message in messages %}
            <div class="alert alert-{{ message.tag }}">
            {{ message }}
            </div>
        {% endfor%}
    {% endif %}
    {% block content %}{% endblock %}
</div>

7. Style the form

We can use Crispy forms 3rd-party application to style our form.

First, we need to install the application: pip install django-crispy-forms

Then, add Crispy form app in mysite/settings.py under users.apps.UsersConfig:

INSTALLED_APPS = [
    'blog.apps.BlogConfig',
    'users.apps.UsersConfig',
    'crispy_forms', # Add crispy_forms app
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

At the bottom of settings.py, set Bootstrap 4 as our CSS template:

CRISPY_TEMPLATE_PACK = 'bootstrap4'

8. Create register.html file

In templates folder, create a sub-directory called users and then create register.html.

└── users
    ├── templates
    │   └── users
    │       └── register.html

9. Edit register.html

We can edit the register layout with Bootstrapp and reference templates from our blog app.

{% extends "blog/base.html" %}
<!-- Load crispy form -->
{% load crispy_forms_tags %} 
{% block content %}

    <div class="content-section">
        <!-- Sign up form -->
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group"> 
                <legend class="border-bottom mb-4">Join us today</legend>
                {{ form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">Sign up</button>
            </div>
        </form>

        <!-- Sign in form -->
        <div class="border-top pt-3">
            <small class="text-muted">
                Already have an account? <a class="ml-2" href="#">Sign in</a>
            </small>
        </div>
    </div>
{% endblock content %}