Introduce Custom User Model in middle of a django project

ยท

3 min read

Hey Guys, Today we will gonna learn about how to implement custom user model in django in the middle of the ongoing project. I will assume you are using Postgres as database for your django project because this blog post will focus on implementing custom user model in django with Postgres databse.

Let's get started..

  • Find all the references(foreign keys/one-to-one/many-to-many) relationships to django's built in User model inside your codebase.

  • Replace all those references by using a generic way to access user model in django with settings.AUTH_USER_MODEL,For that you need to first import settings in all those files and then replace the references like below.

from django.conf import settings

# For example if you have a model with a foreign key relation to user like below
class Example(models.Model):
   user = models.ForeignKey(User)

# Then just change it to something like below
class Example(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
  • Next find all references to django's built in User model inside any of the functions/methods of your codebase and replace them withget_user_model()like below.
from django.contrib.auth import get_user_model

# For example you have any function or method inside any of your file in codebase
def get_all_users():
    return User.objects.all()

# Then just change it to something like below
def get_all_users():
    return get_user_model().objects.all()
  • Once you have done all of the steps above. Now you need to create a fresh app using command below.
python manage.py startapp users

Note: i named my new app as users but you can name it whatever you want.

  • Now open models.py in the users app and create a custom user model like below.
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    class Meta:
        db_table = 'auth_user'

Note: I have named the custom user model as User for the sake of simplicity but you can name it anything. Now pay attention to the db_table meta attribute which i have set to auth_user. I did that because in case you already have users in your postgres database and you want to retain those users, then you will need to set db_table to auth_user.

  • Now open settings.py and add users app in the INSTALLED_APPS like below.
INSTALLED_APPS = [
    # ...
    'users',
]
  • Now also add AUTH_USER_MODEL in settings.py like below.
AUTH_USER_MODEL = 'users.User'

Note: In all these above cases i have used users as my app name, you will need to set them according to your app name.

  • Now create the initial migrations for the user model like below.
python manage.py makemigrations

Note: Now don't try to run python manage.py migrate at this point because it will create an Inconsistent Migration History in django_migrations table and all it will create non-existent content type in django_content_types table.

We can fix this issue by tweaking the postres database tables by ourselves using queries.

  • Now open the terminal and go to the project directory where your manage.py exists and run the below commands one by one.
echo "INSERT INTO django_migrations (app, name, applied) VALUES ('users', '0001_initial', CURRENT_TIMESTAMP);" | python manage.py dbshell

echo "UPDATE django_content_type SET app_label = 'users' WHERE app_label = 'auth' and model = 'user';" | python manage.py dbshell

Note: As you can see in both of these above command i have used users as my app name, make sure to change it in case your app name is different.

  • Now you can go ahead and run the below command.
python manage.py migrate
  • Once the migrate runs successfully. Congrats!!

Now you can go ahead and make changes to the custom user model like add a new field or override any existing field etc.

Did you find this article valuable?

Support Nitin Raturi by becoming a sponsor. Any amount is appreciated!

ย