Extend Django User Model with custom Fields

This tutorial will be based on custom fields in Django, how to extend/customize the default fields. This is going to be a very interesting task, without any further waste of time, let’s move to the introduction part.


You all might already know the Django fields, what all entries we have as an option, or some required fields. By the end of this tutorial, you will be able to modify the model according to your need. For example, you might need to have some extra details like mobile number, branch, college, etc which Django doesn’t provide by default. We have a technique to make this happen too. Moving towards implementation, make sure you are done with the below steps-

  1. Start a project.
  2. Start an app.

Create model

Now it’s time to create our model which consists of some fields namely, email, first name, last name, mobile, and so on.

So open your models.py in your app without any delay.

Here we will create 2 classes, UserManager, and user. For what are we using, UserManager and User class?

The solution to the above question lies in the difference between the 2 classes, UserManager has no fields, except for functions, User has fields like email, password, etc.

from django.db import models
from django.utils import timezone
from django.contrib.auth.base_user import AbstractBaseUser,BaseUserManager
from django.contrib.auth.models import PermissionsMixin

class UserManager(BaseUserManager):

    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError('Email required')

        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be a staff'
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be a superuser'

        return self._create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True,max_length=255,blank=False)
    first_name = models.CharField('first name',max_length=150,blank=True)
    last_name = models.CharField('last name',max_length=150,blank=True)
    mobile= models.PositiveBigIntegerField('mobile',null=True,blank=True)
    is_staff = models.BooleanField('staff status',default=False)
    is_active = models.BooleanField('active',default=False)
    is_superuser = models.BooleanField('superuser',default=False)
    date_joined = models.DateTimeField('date joined',default=timezone.now)
    USERNAME_FIELD = 'email'
    objects = UserManager()

    def __str__(self):
        return self.email

    def full_name(self):
        return self.first_name+" "+self.last_name

The first class UserManager has functions defined which are create_user which will first normalize the email address which means that [email protected] and [email protected] won’t be treated as two different users after that it will save the password and then it will save its user. The next function mainly focuses on its permissions namely, staff, superuser. Next, we have to create a superuser as we all know superuser has all the permissions, it will set the staff, superuser as True.

The class User has been extended from abstractbaseuser which has the power to authenticate and also PermissionMixin which has the power to change the permission like is_superuser(). The rest is our model fields which are email, first name, last name, mobile, is_staff, is_active, is_superuser, date_joined.

Register the model

So, our models are ready, now we need to register our model. You guessed it right. Move to the admin.py file, import User from models, and then register it.

from django.contrib import admin

from .models import User


So we have registered our model too. Now it’s time to authorize our user model in our settings.py as


You can write it anywhere in the settings.py. I wrote it below

ROOT_URLCONF = 'project.urls'. You can do the same.
Now we will migrate the changes.

Migrate the changes

In your terminal execute two commands –

python manage.py makemigrations

python manage.py migrate

We have successfully migrated the changes. We only have to create a superuser to access the Admin panel.

Create Superuser

Write python manage.py createsuperuser in your terminal

It will ask you for some basic details which will be needed later when we log in to the Django Administration.

Run your server

So, we are just one step away to view our basic custom model.

Write python manage.py runserver in your terminal and then navigate to the link provided –

Append admin at the end or navigate into

You will be able to see a screen on clicking on add user –

Extend Django User Model with custom Fields

Extend Django User Model with custom Fields

As you can see in the output screen, we have successfully created a custom model in Django with some fields like the first name, last name, mobile number, date_joined, etc. You might have got a basic idea about how to create a custom model in Django, you can create a model with your customizations too.

Thanks for reading! I hope you found this tutorial helpful and are able to create/extend a custom model in Django.

3 responses to “Extend Django User Model with custom Fields”

  1. Ayush Wagh says:

    (fields.E301) Field defines a relation with the model ‘auth.User’, which has been swapped out.
    HINT: Update the relation to point at ‘settings.AUTH_USER_MODEL’.

    This was the error it is throwing can you please help me out

  2. Ayush Sunil Wagh says:

    How do we use it in Forms
    should i use the model we created here in forms.py?
    can you please help me with it i am stuck on this of five days now

  3. Khushi Aswani says:

    Try dropping the database, then delete your migrations, and then re-running your migration

Leave a Reply

Your email address will not be published. Required fields are marked *