In the previous tutorial, we learned how to combine Django with FastAPI to build a blog covering all aspects of a CRUD project.
We created the models and ORM in Django and a CRUD API Endpoint with FastAPI.
We also set up: validations using pydantic, Django ASGI and WSGI to work together with FastAPI, and a basic API versioning with FastAPI.
In this tutorial, you will learn to create a User Model with FastAPI and Django.
The codes for this tutorial build upon the previous one.
Step 1: Create a Django Accounts App
-
How to Create a Django Accounts App
python manage.py startapp accounts
Create a Django Accounts App. -
Add accounts to Installed App in Django Settings
INSTALLED_APPS = [ ..., "accounts", ]
Add accounts to Installed App.
Step 2: Create a Django User Model and Manager
-
How to Create a Django User Model with Fullname Field and Email
The code below will create a User Model Field with a
fullname
andemail
as a username.from django.contrib.auth.models import AbstractUser from django.db import models from accounts.managers import UserManager class CustomUser(AbstractUser): username = None first_name = None last_name = None password2 = None name = models.CharField(max_length=150) email = models.EmailField(max_length=255, unique=True) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['name'] def __str__(self): return self.email
Create a Django User Model. -
How to Create a Django Manager for a User Model
Create a
manager.py
file in theaccounts
app and add the codes below.from core.utils import get_first_name, get_last_name from django.contrib.auth.models import BaseUserManager from django.core.exceptions import ValidationError from django.db import models from django.utils.translation import gettext_lazy as _ class UserQuerySet(models.QuerySet): pass class UserManager(BaseUserManager): use_in_migrations = True def get_queryset(self): return UserQuerySet(self.model, using=self._db) def _create_user(self, name, email, password, **extra_fields): """ Create and save a user with the given name, email, and password. """ if not email: raise ValueError(_("Users must have an email address")) fullname = name.split() if len(fullname) <= 1: raise ValidationError( _('Kindly enter more than one name.'), code='invalid', params={'value': self}, ) for x in fullname: if len(x) < 2: raise ValidationError( _('Kindly give us your full name.'), code='invalid', params={'value': self}, ) email = self.normalize_email(email) name = ' '.join(map(str, fullname)) user = self.model(name=name, email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_user(self, name, email=None, password=None, **extra_fields): extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) return self._create_user(name, email, password, **extra_fields) def create_staff(self, name, email, password, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', False) if extra_fields.get('is_staff') is not True: raise ValueError('Staff must have is_staff=True.') return self._create_user(name, email, password, **extra_fields) def create_superuser(self, name, email, password, **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('Admin must have is_staff=True.') if extra_fields.get('is_superuser') is not True: raise ValueError('Admin must have is_superuser=True.') return self._create_user(name, email, password, **extra_fields) def get_full_name(self): return self.name def get_short_name(self): return get_first_name(self.name) def get_first_name(self): return get_first_name(self.name) def get_last_name(self): return get_last_name(self.name)
Create a Django Manager. -
How to Add an Admin for a Django User Model
from django.contrib import admin from django.contrib.auth import get_user_model from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.utils.translation import gettext_lazy as _ from .forms import UserAdminChangeForm, UserAdminCreationForm User = get_user_model() class UserAdmin(BaseUserAdmin): # The forms to add and change user instances add_form = UserAdminCreationForm form = UserAdminChangeForm # inlines = [ # ProfileInline, # ] fieldsets = ( # (None, {'fields': ('password',)}), # This simply shows the hashed password field (_('Personal info'), {'fields': ('name', 'email',)}), (_('Permissions'), { 'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions',) }), (_('Important dates'), {'fields': ('last_login', 'date_joined',)}), ) # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin # overrides get_fieldsets to use this attribute when creating a user. add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('name', 'email', 'password1', 'password2')} ), ) list_display = ('id', 'email', 'name', 'is_active', 'is_staff') list_display_links = ['email'] list_filter = ('is_superuser', 'is_staff', 'is_active', 'groups') search_fields = ('email', 'name') ordering = ('email',) list_per_page = 10 filter_horizontal = ('groups', 'user_permissions',) admin.site.register(User, UserAdmin)
Add an Admin for a Django User. -
Add the helper functions below to the
utils.py
file in the core moduledef get_first_name(self): if isinstance(self, bool): pass else: names = self.split() return names[0] def get_last_name(self): if isinstance(self, bool): pass else: names = self.split() return names[-1]
Add helper functions.
Step 3: Migrate the Models
Run the commands below to migrate our user model's data.
python manage.py makemigrations
python manage.py migrate
Step 4: Create a Super User
Run the command below to create a superuser for our app.
python manage.py createsuperuser
If you successfully created a superuser, run the django server and log in to the admin page to test our models.
python manage.py runserver
Wrap Off
In this tutorial, we focused on Django mainly to add a user model to the project.
Next, we will improve the accounts app to be production-ready. We will use Django Rest Framework and Django packages like Django AllAuth, dj-rest-auth for authentication and authorization.