In this article, we will be learning how to create a custom user model in Django. Why do you need a custom user while Django has it's own auth models? Well, the default user class doesn't offer adequate fields that may fully describe a user based on the type of application you're building. For instance, you may want to add the full name, gender, location, etc. Worry not since even with all that abstraction that comes with Django we can still be able to tweak a couple of things. Let's get to it.
Let's Build
I am assuming you've already created a Django app and configured the database. I will be using Django 3.0.1 and Postgres 12.1. First, since the user model overrides the default user we need to define a custom UserManager
class that extends BaseUserManager
. We also have to ensure the class defines two methods; create_user
and create_superuser
methods. Create the user manager file under your startapp folder. Mine is in the path src/authentication/user_manager.py
. Below is my project directory structure:
user_manager.py
"""User manager model module"""
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
"""
custom user model
"""
def create_user(
self,
email,
password,
is_active=False,
is_staff=False,
is_admin=False
):
"""Create user."""
if not email:
raise ValueError('Users must have an email address')
user = self.model(email=self.normalize_email(email))
user.is_active=is_active
user.is_staff=is_staff
user.is_admin=is_admin
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""Create a superuser."""
return self.create_user(
email,
password,
is_active=True,
is_staff=True,
is_admin=True
)
For the user to have superuser permissions like site administration, you have to add is_superuser=True
or have the has_perm
class method in your user model that references the admin field. In this case, we're going with the latter.
Create a User
model in the models file as below. Feel free to add any other fields as deemed necessary.
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from authentication.user_manager import UserManager
class User(AbstractBaseUser, PermissionsMixin):
"""User model."""
email = models.EmailField(unique=True, null=False)
first_name = models.CharField(max_length=30, null=True)
last_name = models.CharField(max_length=30, null=True)
password = models.CharField(max_length=128, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True, null=True)
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
objects = UserManager()
#unique identifier
USERNAME_FIELD = 'email'
# any required fields besides email and password
REQUIRED_FIELDS = []
def __str__(self):
return f'{self.first_name} {self.last_name}'
@property
def is_superuser(self):
return self.is_admin
def has_perm(self, perm, obj=None):
return self.is_admin
AbstractBaseUser
: Allows us to create a completely new User model.
PermissionsMixin
: It will add fields that are specific for objects that have permissions, like is_admin
.
Now add {app_name}.User
to your settings.py
file:
AUTH_USER_MODEL = 'authentication.User'
Finally run the migrations. $ python manage.py makemigrations && python manage.py migrate
To be able to login to the admin dashboard we have to register our custom User
model in Django admin sites. Open app_name/admin.py
and add the code below.
"""Register models to django admin."""
from django.contrib import admin
from django.contrib.auth.models import Group
from authentication.models import User
# list other models here
MODELS = []
class UserAdmin(admin.ModelAdmin):
"""Customize user/admin view on djano admin."""
search_fields = ('email', )
list_display = ('email', 'is_admin')
list_filter = ('is_active', 'is_admin')
ordering = ('email', )
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Permissions', {'fields': ('is_admin','is_staff')}),
('Primary personal information', {
'fields': ('first_name', 'last_name')}),
('Status', {'fields': ('is_active', )}),
)
admin.site.register(User, UserAdmin)
for model in MODELS:
admin.site.register(model)
To test the app start by creating a superuser:
Great! Now visit http://127.0.0.1:8000/admin/
to login.
Conclusion
That's all for this article. You should now be able to tweak your user model to fit your application needs. Remember to add any new models under MODELS
list of the admin file. I hope you found it valuable and look out for more in the future!
Top comments (1)
password isnt hashed while saving user from admin