AbstractBaseUser is Flexible and Not So Complicated

AbstractBaseUser-Django django

Define AbstractBaseUser before first migration

Before you migrate for the first time, I recommend that you consider which of the following types of users are right for your project.

Types of User Model

User (standard model)
Abstract User — Fields can be customized (added/changed).
AbstractBaseUser — Fields can be customized (add/change/delete).

Don’t forget to set AbstractBaseUser before your first migration.

In case of User & AbstractUser after migration

When using User (standard model) and AbstractUser, the following fields are created.

The basic information necessary for a blog posting application etc. is created.

    ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    ('password', models.CharField(max_length=128, verbose_name='password')),
    ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
    ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
    ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
    ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
    ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
    ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
    ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
    ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
    ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
    ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
    ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),

Customize initial settings with AbstractBaseUser

‘from django.core.validators import MinLengthValidator, RegexValidator’ is for validating by username (not necessary if you don’t need)

Make sure ‘Active by’ default during registration, WITHOUT staff or admin permissions by setting:

is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)

This project is assuming a user for student charts for lessons filled out by instructors. Models such as registered courses, teaching materials, and lessons will be added at a later date and read as ForeignKeys.

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

# For validating by username
from django.core.validators import MinLengthValidator, RegexValidator

class MyUser(AbstractBaseUser, PermissionsMixin):

    username = models.CharField(verbose_name='username', max_length=10, unique=True, validators=[MinLengthValidator(5,), RegexValidator(r'^[a-zA-Z0-9]*$',)])
    first_name = models.CharField(blank=True, max_length=50, verbose_name='first name')
    last_name = models.CharField(blank=True, max_length=50, verbose_name='last name')
    email = models.EmailField(verbose_name='Email', max_length=50, unique=True)
    date_of_birth = models.DateField(verbose_name="Birthday", blank=True, null=True)
    introduction = models.TextField(verbose_name='Introduction', max_length=300, blank=True, null=True)
    date_joined = models.DateTimeField(verbose_name='Registered', auto_now_add=True)

    # Active by default during registration, without staff or admin permissions
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)

    # AbstractBaseUser requires MyUserManager
    objects = MyUserManager()
    # Used as a unique identifier
    USERNAME_FIELD = 'email'
    # List of field names to be prompted when creating a user。
    REQUIRED_FIELDS = ['username']

    def __str__(self):
        return self.username

Add MyUserManager for BaseUserManager

Define BaseUserManager with MyUserManager.

For example, define how to deal with missing username and email entries, as well as superuser.

Add the following code “before” the description of MyUser.

class MyUserManager(BaseUserManager):
    def create_user(self, username, email, password=None):
        if not username:
            raise ValueError('Users must have an username')
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
        return user

    def create_superuser(self, username, email, password):
        user = self.create_user(
        return user

Customize Admin Panel

First, import MyUser from app/models.

@admin.register(MyUser) enables to show MyUser Model on admin panel.

Then, add list_display to customize what to show on admin panel.

from django.contrib import admin

# Register your models here.
from student.models import MyUser

# Show items you want on the admin-site
class MyUserAdmin(admin.ModelAdmin):
    list_display = ('id', 'username', 'first_name', 'last_name', 'email', 'date_of_birth')

When logged in admin panel, you’ll find STUDENT/My users

Click My users to show a list of users.

Currently, only me is registered.

The detail of list_display set on admin.py is shown.

For basic routing settings, see this post

For Django Official site: Customizing authentication in Django