DigitalOcean Referral Badge
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 startapp accounts

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

# accounts/

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

# customusertutorail/


    # MY APPS
    'accounts',     #add this


AUTH_USER_MODEL = 'accounts.MyUser'  #add this

Create in accounts folder and add the following classes:

# accounts/

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 file to display the custom fields and also to make them editable through admin.

# users/
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, MyUserAdmin)

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

$ python makemigrations
$ python migrate

Create a Superuser

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

$ python createsuperuser

Username: yourname
Email address:
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

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 to use the templates

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

# customusertutorial/

        '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

# customusertutorial/


Creating views

Head to file in accounts and create the SignUpView.

# accounts/

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 ‘’ in accounts and add the following code:-

# accounts/

from django.urls import path
from .views import SignUpView

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

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

# customusertutorial/

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('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 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

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
Best way to start a Django project (with Github Integration)
By Udit Vashisht

Correct way to create a Django Project

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 ...

Read More
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
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 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 bioinformatics fastafiles Fasta python list append append raspberry pi editor cron crontab Cowin Cowin api python dictionary Python basics dictionary python list list ios development listview navigationview swiftui ios mvvm swift environmentobject property wrapper @State @Environm popup @State ios15 alert automation instagram instaloader texteditor youtubeshorts textfield multi-line star rating reusable swift selenium selenium driver requests-html youtube youtube shorts python automation python tutorial algo trading nifty 50 nifty50 stock list nifty50 telegram telegram bot dictionary in Python how to learn python learn python