Migrating to a Custom User Model mid-project in Django
Whenever you are building a site with Django that will have user authentication, it is recommended to create a Custom User Model before the first migration. Sometimes you forget to do that. In this case, you have to follow a strict procedure, which I’ll show you in the post.
This was Issue was discussed at length by the Django community. There is now a consensus about the best and the least painful way to do that. I’d like to take that discussion and summarize it into a set of actionable steps.
1. Create the users
app
Make sure you are inside your project directory.
python manage.py startapp users
Then, add the following to the models.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
class Meta:
db_table = 'auth_user'
If you don’t specify the name, you’ll receive an error:
django.db.utils.OperationalError: no such table: users_customuser
Then, register the new Model in the admin panel:
# In users/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
model = CustomUser
admin.site.register(CustomUser, CustomUserAdmin)
2. Update settings.py
file
- In
settings.py
add toINSTALLED_APPS
("users.apps.UsersConfig",
) - Add a
AUTH_USER_MODEL = 'users.CustomUser'
line to the bottom of thesetting.py
file.
3. Replace User imports
In your project code, replace all imports of the Django User model:
from django.contrib.auth.models import User
with the new, custom one:
from users.models import User
4. Delete Old Migrations
Run the following two commands in your terminal, from the root of your project:
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
5. Create New Migrations
python manage.py makemigrations
6. Truncate (delete) contents of the migrations table
You will need to do this manually by going inside your database (Postgres, sqlite3, MySQL, etc.).
I was using sqlite3 at the time, so I had to do the following:
# login into the sqlite database
sqlite3 db.sqlite
# Then run the following
> DELETE FROM django_migrations;
> .quit
If you are using Postgres, you will have to first login into your database and then run:
TRUNCATE TABLE django_migrations;
7. Fake apply new migrations
python manage.py migrate --fake
8. Test
python manage.py runserver
This should be it. If you went through each step sequentially, your app should be using a Custom User Model. Congrats!
Bonus Video
If you prefer a more visual approach, I’ve made a video that shows how to migrate to a Custom User Model mid-project.