Udit Vashisht
Author: Udit Vashisht

How to Extend Django User model using AbstractUser?

  • 6 minutes read
How to Extend Django User model using AbstractUser?

    Table of Contents

Even if the default Django User Model caters to all of your needs, it is highly recommended to use a Custom User Model. Django’s official documentation recommends so. Now there are two ways to create a Custom User Model:-

  1. By extending AbstractBaseUser
  2. By extending AbstractUser

The first method involves more complicated steps and should be used only when you are sure of what you are doing (Don’t worry, we are coming up with a complete tutorial on that too). In this tutorial we will be extending the AbstractUser which is a subclass of AbstractBaseUser.

Why to create a Custom User Model?
Before, going into how to do it, it is very important to explain why should we use the custom model. Let us take an example, you are running a project and you have used the built-in User model. Now, after sometime your project has expanded a lot and you now want to add extra fields say Mobile Number to your user model. At this point, changing your built-in model would be a big task. However, if you would have chosen a custom user model at the very beginning of your project. You could have easily added the new field.

How to extend Django User Model using AbstractUser?

AbstractUser class inherits the User class and is used to add additional fields required for your User in the database itself. So, it changes the schema of the database. It is basically used to add fields like bio, location, date of birth etc. to the existing User model. This must be done at the very beginning of the project.

Create a new project

Create an empty project with name ‘Customusertutorial’ as detailed in this tutorial.

Now, create a new app called ‘accounts’:

$ python manage.py startapp accounts

In models.py file create a new class of CustomUser as under:-

# accounts/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.

class MyUser(AbstractUser):
    mobile_number = models.CharField(max_length=10, unique=True)
    birth_date = models.DateField(null=True, blank=True)

Now add this app in installed app of your settings.py

# customusertutorail/settings.py


    # MY APPS
    'accounts',     #add this


AUTH_USER_MODEL = 'accounts.MyUser'  #add this

Create forms.py in accounts folder and add the following classes:

# accounts/forms.py

from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import MyUser

class MyUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = MyUser
        fields = ('username', 'mobile_number', 'birth_date')

class MyUserChangeForm(UserChangeForm):

    class Meta(UserChangeForm):
        model = MyUser
        fields = ('username', 'mobile_number', 'birth_date')

Edit, the admin.py file to display the custom fields and also to make them editable through admin.

# users/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin

from .forms import MyUserCreationForm, MyUserChangeForm
from .models import MyUser

class MyUserAdmin(UserAdmin):
    add_form = MyUserCreationForm
    form = MyUserChangeForm
    model = MyUser
    list_display = ['username', 'mobile_number', 'birth_date']
    fieldsets = UserAdmin.fieldsets + (
            (None, {'fields': ('mobile_number', 'birth_date')}),
    ) #this will allow to change these fields in admin module

admin.site.register(MyUser, MyUserAdmin)

After saving all the files, run makemigrations and migrate command.

$ python manage.py makemigrations
$ python manage.py migrate

Create a Superuser

Run the following command and fill up the credentials to create the superuser:

$ python manage.py createsuperuser

Username: yourname
Email address: your@email.com
Password (again): 
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

Creating Templates

Create a directory ‘templates’ inside your project directory i.e. the directory which contains manage.py

Now, inside the ‘templates’ directory create three files ‘base.html’ , ‘home.html’ and ‘signup.html’

<!-- templates/base.html -->
<!DOCTYPE html>
  <meta charset="utf-8">
        {% block title %}
        Welcome to SaralGyaan
        {% endblock %}
    {% block content %}
    {% endblock %}
<!-- templates/home.html -->
{% extends 'base.html' %}
{% block title %}
{% endblock %}

{% block content %}
{% if user.is_authenticated %}
  <h3>Hi {{ user.username }}! </h3>
  <p>Welcome to SaralGyaan</p>
  <p><a href="{% url 'logout' %}">logout</a></p>
{% else %}
  <p>Welcome to SaralGyaan</p>
  <p>Kindly login or signup</p>
  <a href="{% url 'login' %}">Login</a> |
  <a href="{% url 'accounts:signup' %}">Sign Up</a>
{% endif %}
{% endblock %}
<!-- templates/signup.html -->
{% extends 'base.html' %}

{% block title %}
Signup - SaralGyaan
{% endblock %}

{% block content %}
<h2>Sign up to SaralGyaan</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Sign up</button>
{% endblock %}

Lastly, create a directory ‘registration’ inside the ‘templates’ and create a file ‘login.html’

<!-- templates/registration/login.html -->
{% extends 'base.html' %}

{% block title %}
Login - SaralGyaan
{% endblock %}

{% block content %}
<h2>Login to SaralGyaan</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Login</button>
{% endblock %}

Update settings.py to use the templates

Update the settings.py file to use the templates directory which we have created above:

# customusertutorial/settings.py

        'DIRS': [os.path.join(BASE_DIR, 'templates')], # add this

On login and log out we want to re-direct our users to the home page. To do the same, update the settings.py:

# customusertutorial/settings.py


Creating views

Head to views.py file in accounts and create the SignUpView.

# accounts/views.py

from django.urls import reverse_lazy
from django.views.generic.edit import CreateView

from .forms import MyUserCreationForm

class SignUpView(CreateView):
    form_class = MyUserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

Defining urls

Finally, we need to define the urls for Signup, login and home view. Create a new file ‘urls.py’ in accounts and add the following code:-

# accounts/urls.py

from django.urls import path
from .views import SignUpView

urlpatterns = [
    path('signup/', SignUpView.as_view(), name='signup'),

Go to project’s urls.py and add the following code:-

# customusertutorial/urls.py

from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView

urlpatterns = [
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
    path('admin/', admin.site.urls),
    path('accounts/', include(('accounts.urls', 'accounts'))),
    path('accounts/', include('django.contrib.auth.urls')),

Run the Server

Now, run the server using the following command and check the home page, login page, signup page etc.

$ python manage.py runserver


Screenshot 2019-08-08 at 2.43.02 PM.png


Screenshot 2019-08-08 at 2.43.14 PM.png


Screenshot 2019-08-08 at 2.44.25 PM.png

Homepage when user is logged-in

Screenshot 2019-08-08 at 2.43.31 PM.png

The complete code can be downloaded from here

Hope you have enjoyed this tutorials. Please share, like and comment.

Related Posts

Django Database Migrations: A Comprehensive Overview
By Udit Vashisht

Introduction to Django databases

The Django web framework is designed to work with an SQL-based relational database backend, most commonly PostgreSQL or MySQL. If you’ve never worked directly with a relational database before, managing how your data is stored/accessed and keeping it consistent with your application code ...

Read More
Best way to start a Django project (with Github Integration)
By Udit Vashisht

There are dozens of ways, which developers use to start their Django projects. Possibly, none of them would be a wrong way, but in this post we will be telling you a way which is very helpful and suitable not only in development but also in production (deployment). Not only ...

Read More
How to extend Django User model using a proxy model?
By Udit Vashisht

There is no doubt that the built-in user authentication system of Django is quite good and caters the common use cases. But sometimes, we do not have our needs met with out-of-the-box defaults django user model. In such a scenario, we can extend the Django User Model using various methods. ...

Read More
tech tutorials automate python beautifulsoup web scrapping webscrapping bs4 Strip Python3 programming Pythonanywhere free Online Hosting hindi til github today i learned Windows Installations Installation Learn Python in Hindi Python Tutorials Beginners macos installation guide linux SaralGyaan Saral Gyaan json in python JSON to CSV Convert json to csv python in hindi convert json csv in python remove background python mini projects background removal remove.bg tweepy Django Django tutorials Django for beginners Django Free tutorials Proxy Models User Models AbstractUser UserModel convert json to csv python json to csv python Variables Python cheats Quick tips == and is f string in python f-strings pep-498 formatting in python python f string smtplib python send email with attachment python send email automated emails python python send email gmail automated email sending passwords secrets environment variables if name == main Matplotlib tutorial Matplotlib lists pandas Scatter Plot Time Series Data Live plots Matplotlib Subplots Matplotlib Candlesticks plots Tutorial Logging unittest testing python test Object Oriented Programming Python OOP Database Database Migration Python 3.8 Walrus Operator Data Analysis Pandas Dataframe Pandas Series Dataframe index pandas index python pandas tutorial python pandas python pandas dataframe python f-strings padding how to flatten a nested json nested json to csv json to csv python pandas Pandas Tutorial insert rows pandas pandas append list line charts line plots in python Django proxy user model django custom user model django user model matplotlib marker size pytplot legends scatter plot python pandas python virtual environment virtualenv venv python python venv virtual environment in python python decorators