Custom User In Django
Tags: python, django, customuserdjango, webdev
Published: 2023-03-26 11:49:34




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()
```
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']
```
**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',
]
```

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),
]
```

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'
```
**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'

```
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',
]
```
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),
]
```
** 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)
```


**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](https://github.com/gajanan0707/DjnagoCustomeUser) repo.

Let’s Get in Touch! Follow me on:

>Instagram: [@rajput_gajanan_07](https://www.instagram.com/rajput_gajanan_07/).

>GitHub: [@gajanan0707](https://github.com/gajanan0707)

>Linkedin: [Gajanan Rajput](https://www.linkedin.com/in/gajanan-patil-0124b7145/)