Django comes with a default user model that's used for the standard authentication system. If you had worked on Django you probably have seen this authentication page.
We're going to override this model with our own custom model that allows us to use an
Username that comes with the Django default model.
We're gonna modify
models.py file to include our user profile model.
The first thing we need to do is import some additional classes at the top.
According to Django documentation
AbstractBaseUser has the authentication functionality only , it has no actual fields, you will supply the fields to use when you subclass.
PermissionsMixin. This is an abstract model you can include in the class hierarchy for your user model, giving you all the methods and database fields necessary to support Django’s permission model.
If your user model defines
date_joined fields the same as Django’s default user, you can install Django’s
UserManager; however, if your user model defines different fields, you’ll need to define a custom manager that extends
Add this lines at top of the file.
from django.contrib.auth.models import AbstractBaseUser from django.contrib.auth.models import PermissionsMixin from django.contrib.auth.models import BaseUserManager
Creating UserProfile Class.
Underneath the imports let's create a new class called
UserProfile and inherit from the
class UserProfile(AbstractBaseUser, PermissionsMixin): """ Database model for users in the system """ email = models.EmailField(max_length=255, unique=True) name = models.CharField(max_length=255) objects = UserProfileManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['name'] def __str__(self): """ Return string representation of our user """ return self.email
By adding above code we:
- Made the
namefield required and made
- Set the
USERNAME_FIELDwhich defines the unique identifier for the
- Specified that all objects for the class come from the
Creating UserProfileManager Class.
Now that we have our custom user model we can go ahead and create a manager. Now because we've customized our model we need to tell Django how to interact with this user model in order to create users because by default when it creates a user it expects a user name field and password field but we replace the user name field with an email field.So we just need to create a custom manager that can handle creating users with an email field instead of a user name field.
Let's create a new class called
UserProfileManager and inherit from the
class UserProfileManager(BaseUserManager): """ Manager for user profiles """
UserProfileManager the way it manages work is you specify
some functions within the manager that can be used to manipulate objects within the module that the manager is for.
Below are two functions which we need to add in
def create_user(self, email, name, password=None): """ Create a new user profile """ if not email: raise ValueError('User must have an email address') email = self.normalize_email(email) user = self.model(email=email, name=name) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, name, password): """ Create a new superuser profile """ user = self.create_user(email,name, password) user.is_superuser = True user.is_staff = True user.save(using=self._db) return user
Above code sets logic for when one creates users and superusers using Django CLI.
Update Settings to use Custom Model.
We need add below line in
settings.py to use this model over default one.
AUTH_USER_MODEL = 'App_name.UserProfile'
Make changes in Database.
Create new migrations and migrate them which will create a new database that uses our custom User Model:
$ python manage.py makemigrations $ python manage.py migrate
$ python manage.py createsuperuser Email address: email@example.com Password: Password (again): Superuser created successfully.
As you can see instead of asking for
Username it is prompting for
Top comments (1)
This will crash after login and bring all kinds of issues as the user is missing required fields (e.g. is_stuff)