In this section, we will explore how to create and use custom user models in Django. By default, Django provides a built-in user model, but in many cases, you may need to extend or customize this model to fit your application's requirements.

Why Use Custom User Models?

  • Flexibility: Custom user models allow you to add additional fields and methods to the user model.
  • Scalability: Custom user models can be tailored to meet the specific needs of your application, making it more scalable.
  • Future-Proofing: It's easier to make changes to a custom user model than to the default user model once your application is in production.

Steps to Create a Custom User Model

  1. Create a New Django App: It's a good practice to create a new app specifically for user management.
  2. Define the Custom User Model: Extend Django's AbstractBaseUser and PermissionsMixin classes.
  3. Create a User Manager: Define a custom manager for the user model.
  4. Update Settings: Configure Django to use the custom user model.
  5. Create and Apply Migrations: Generate and apply database migrations for the new user model.

Step 1: Create a New Django App

First, create a new app for user management:

python manage.py startapp accounts

Step 2: Define the Custom User Model

In the accounts/models.py file, define your custom user model:

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

class CustomUserManager(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 CustomUser(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_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

Step 3: Update Settings

In your settings.py file, update the AUTH_USER_MODEL setting to point to your custom user model:

AUTH_USER_MODEL = 'accounts.CustomUser'

Step 4: Create and Apply Migrations

Generate and apply the migrations for your custom user model:

python manage.py makemigrations accounts
python manage.py migrate

Practical Example

Let's create a simple view to register a new user using the custom user model.

accounts/forms.py

from django import forms
from .models import CustomUser

class CustomUserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)

    class Meta:
        model = CustomUser
        fields = ('email', 'first_name', 'last_name')

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

accounts/views.py

from django.shortcuts import render, redirect
from .forms import CustomUserCreationForm

def register(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('login')
    else:
        form = CustomUserCreationForm()
    return render(request, 'accounts/register.html', {'form': form})

accounts/urls.py

from django.urls import path
from .views import register

urlpatterns = [
    path('register/', register, name='register'),
]

templates/accounts/register.html

<!DOCTYPE html>
<html>
<head>
    <title>Register</title>
</head>
<body>
    <h2>Register</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Register</button>
    </form>
</body>
</html>

Common Mistakes and Tips

  • Missing AUTH_USER_MODEL Setting: Ensure you have set AUTH_USER_MODEL in your settings.py.
  • Migrations: Always run makemigrations and migrate after creating or modifying models.
  • Password Handling: Use set_password method to handle password hashing.

Conclusion

In this section, we learned how to create and use custom user models in Django. Custom user models provide flexibility and scalability, allowing you to tailor the user model to your application's specific needs. We covered the steps to create a custom user model, update settings, and create a simple user registration view. This knowledge prepares you for more advanced user management tasks in Django.

© Copyright 2024. All rights reserved