DEV Community

Mr #1738
Mr #1738

Posted on • Edited on

Introduction to Django's Default User Model

By default ,Django comes with a Usermodel that includes username,email, password and etc.However,to make changes usingemail instead of username you will need to customize this User model.

  1. Why Customize the User Model?. Customizing the user model allows you to:
  2. Use email as the login field instead of username.
  • Add the extra field like phone_number or profile_picture.

  • Implement Custom user roles and permissions.

  1. Steps to Customize the User Model.

Step 1 :Create a Custom Model
Django recommends using Custom user model at the beginning of your project to avoid complications later.Here's how to define a custom user model:
Create the custom user modelin app's models.py file .


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

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("The Email field must be set")
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

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

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

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

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def __str__(self):
        return self.email
Enter fullscreen mode Exit fullscreen mode

In this example:

  • The custom User model uses email as the unique identifier [USERNAME_FIELD] -UserManageris used to handle user creation.

Step2:Update settings.py.
Tell django to update custom user model by adding this line to settings.py.

# settings.py

AUTH_USER_MODEL = 'yourapp.User'
Enter fullscreen mode Exit fullscreen mode

Step3:Run migrations
Once the custom user model is defined and updated , you will need to make and apply migrations.

python3 manage.py makemigrations
python3 manage.py migrate
Enter fullscreen mode Exit fullscreen mode

3.Create a Custom User manager.

  • The UserManager class helps to manage user creation for both users and superusers.
  • create_user:Handles normal user creation with password hashing.
  • create_superuser: Handles superuser creations with necessary permissions.

You've already added UserManager in Usermodel Above.

4.Customizing the Admin Panel for the User Model.
To manage users via admin interface in Django, you will need to register user modeland customize the admin form.

# yourapp/admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

class CustomUserAdmin(UserAdmin):
    model = User
    list_display = ['email', 'first_name', 'last_name', 'is_staff']
    search_fields = ['email', 'first_name', 'last_name']
    ordering = ['email']

admin.site.register(User, CustomUserAdmin)

Enter fullscreen mode Exit fullscreen mode

This register Custom user model and adds it to admin interface.

5.Adding extra Fields to the User Model
You can easily extend custom user with extra fields.For example, you might want to add phone_numberand profile_picture.

# yourapp/models.py
class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    phone_number = models.CharField(max_length=15, blank=True, null=True)
    profile_picture = models.ImageField(upload_to='profile_pics/', blank=True, null=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

Enter fullscreen mode Exit fullscreen mode

Make sure to run migrations after adding new fields.

python manage.py makemigrations
python manage.py migrate

Enter fullscreen mode Exit fullscreen mode

6.Customizing User authentication.
To log in users to use the email instead of username,create a custom authentication back-end:

# yourapp/backends.py
from django.contrib.auth.backends import BaseBackend
from .models import User

class EmailBackend(BaseBackend):
    def authenticate(self, request, email=None, password=None):
        try:
            user = User.objects.get(email=email)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Enter fullscreen mode Exit fullscreen mode

Then,update your settings.py to use the authentication back-end:

settings.py

AUTHENTICATION_BACKENDS = ['yourapp.backends.EmailBackend']

**7.User Registration and Login-Views**
You can now create custom views for `user ``registration` and `login.` Here’s an example using Django REST Framework:

Enter fullscreen mode Exit fullscreen mode

yourapp/views.py

from rest_framework import generics
from .models import User
from .serializers import UserSerializer
from rest_framework.permissions import AllowAny

class RegisterUserView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [AllowAny]

The corresponding `serializer` would look something like this:

Enter fullscreen mode Exit fullscreen mode

yourapp/serializers.py

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'first_name', 'last_name', 'password']

def create(self, validated_data):
    user = User(
        email=validated_data['email'],
        first_name=validated_data['first_name'],
        last_name=validated_data['last_name']
    )
    user.set_password(validated_data['password'])
    user.save()
    return user
Enter fullscreen mode Exit fullscreen mode

**8. Testing and Validating Custom User Models**
Testing is critical to ensure everything works as expected. Create tests to verify `user ``registration` and authentication processes:

Enter fullscreen mode Exit fullscreen mode

yourapp/tests.py

from django.test import TestCase
from .models import User

class UserTestCase(TestCase):
def setUp(self):
User.objects.create_user(email='testuser@example.com', password='password')

def test_user_creation(self):
    user = User.objects.get(email='testuser@example.com')
    self.assertEqual(user.email, 'testuser@example.com')
Enter fullscreen mode Exit fullscreen mode



**9. Conclusion**
Customizing Django's user model offers flexibility to suit project-specific needs. By creating a custom user model, you can easily extend it, implement email-based authentication, and manage users more effectively.










Enter fullscreen mode Exit fullscreen mode

Top comments (0)