Custom User In Django

Gajanan Rajput - Mar 26 '23 - - Dev Community

This post explains step-by-step how to create a custom User model in Django.

Objectives
By the end of this article, you should be able to:

  • Describe the difference between AbstractUser and AbstractBaseUser
  • Explain why you should set up a custom User model when starting a new Django project.
  • Start a new Django project with a custom User model.
  • Adding Custom fields like avatar, MobileNo fields.
  • Practice test-first development while implementing a custom User model.

AbstractUser vs AbstractBaseUser
Django documentation says that AbstractUser provides the full implementation of the default User as an abstract model, which means you will get the complete fields which come with User model plus the fields that you define.

Example

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

class MyUser(AbstractUser):
    address = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField()
Enter fullscreen mode Exit fullscreen mode

In the above example, you will get all the fields of the User model plus the fields we defined here which are address and birth_date

AbstractBaseUser has the authentication functionality only , it has no actual fields, you will supply the fields to use when you subclass.

You also have to tell it what field will represents the username, the fields that are required, and how those users will be managed.

Lets say you want to use email in your authentication , Django normally uses username in authentication, so how do you change it to use email ?

Example

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

class MyUser(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    objects = MyUserManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']
Enter fullscreen mode Exit fullscreen mode

USERNAME_FIELD is a string describing the name of the field on the user model that is used as the unique identifier.

In the above example, the field email is used as the identifying field.

It is important to note that you can also set email as your unique identifier by using AbstractUser, this can be done by setting username = None and USERNAME_FIELD = 'email'

Project Setup
Start by creating a new Django project along with a users app:


$ mkdir custom-user-model && cd custom-user-model
$ python3 -m venv env
$ source env/bin/activate
(env)$ pip install Django==3.2.2
(env)$ django-admin startproject customeUsesr.
(env)$ python manage.py startapp account

Feel free to swap out virtualenv and Pip for Poetry or Pipenv. For more, review Modern Python Environments.

DO NOT apply the migrations. Remember: You must create the custom User model before you apply your first migration.

Add the new app to the INSTALLED_APPS list in settings.py:
1) first comment in installed_apps this line'django.contrib.admin',

INSTALLED_APPS = [
    #'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'account',
]
Enter fullscreen mode Exit fullscreen mode

2) second comment in urls file path(‘admin/’, admin.site.urls)

from django.contrib import admin
from django.urls import path

urlpatterns = [
   #path('admin/', admin.site.urls),
]
Enter fullscreen mode Exit fullscreen mode

3)open account folder and open file Models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils.translation import ugettext_lazy as _

# Create your models here.
class User(AbstractUser):
    username = models.CharField(max_length=30, unique=True)
    email = models.EmailField(_('email address'),     max_length=254,unique=True, null=True, blank=True)
    avtar = models.ImageField(upload_to='thumbpath', blank=True)
    mobile_no = models.CharField(max_lenght=15)
    class Meta(AbstractUser.Meta):
       swappable = 'AUTH_USER_MODEL'
Enter fullscreen mode Exit fullscreen mode

Settings
Add the following line to the settings.py file so that Django knows to use the new User class:

AUTH_USER_MODEL = 'account.User'
swappable = 'AUTH_USER_MODEL'

Enter fullscreen mode Exit fullscreen mode

Now, you can create and apply the migrations, which will create a new database that uses the custom User model.

(env)$ python manage.py makemigrations
(env)$ python manage.py migrate

Then now uncomment the INSTALLED_APPS list in settings.py
Uncomment in installed_apps this line 'django.contrib.admin',

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'account',
]
Enter fullscreen mode Exit fullscreen mode

second comment in urls file path(‘admin/’, admin.site.urls)

from django.contrib import admin
from django.urls import path

urlpatterns = [
   path('admin/', admin.site.urls),
]
Enter fullscreen mode Exit fullscreen mode

** create a superuser.**

(env)$ python manage.py createsuperuser
Email address: test@test.com
Password:
Password (again):
Superuser created successfully.

*then later open /account/admin.py register user model

from django.contrib import admin
from .models import User, UserProfile
# Register your models here.
admin.site.register(User)
Enter fullscreen mode Exit fullscreen mode

Conclusion
In this post, we looked at how to create a custom User model

You can find the final code for both options, AbstractUser and AbstractBaseUser, in the django-custom-user-model repo.

Let’s Get in Touch! Follow me on:

Instagram: @rajput_gajanan_07.

GitHub: @gajanan0707

Linkedin: Gajanan Rajput

. . . . . . . . . . . . . . . . . . . .