Django: Changing User Model in Mid-Project
Jan 03, 2019 · 3 Min Read · 0 Like · 6 Comments
Every now and then I see some questions pop up in Stack Overflow with title:
ValueError: Related model ‘app.User’ cannot be resolved
This is a very common issue and pops up when the user tries to run the migration. So, lets talk more about what is this problem and how can we solve it.
The problem
This error occurs when you have been using Django’s default User model, and in mid project, you need some changes in auth.User model and decided to use CustomUser.
Why It occurs
As per django documentation:
Changing AUTH_USER_MODEL after you’ve created database tables is significantly more difficult since it affects foreign keys and many-to-many relationship.
As auth.User is core part of Django, and when you change the tables, it can’t work properly. This problem is hard to identify even for myself, because of the error it throws due to migration.
Solution: easy way
The easiest(and cleanest) way is to delete all your migration files from all apps, drop the database. Then create a new database and connect your project to that. Then run python manage.py makemigrations
and python manage.py migrate
to make changes in DB. Means to make a clean start for the project, data wise.
Solution: hard Way
Dropping the Database is not always possible for us. So there is an another approach to resolve this issue(based on ticket #25313):
Create a custom user model identical to auth.User, call it
User
(so many-to-many tables keep the same name) and setdb_table='auth_user'
(so it uses the same table). Like this:from django.contrib.auth.models import AbstractUser class User(AbstractUser): class Meta: db_table='auth_user'
Throw away all your migrations from all the apps(except for
__init__.py
file inside the migrations folder).Now update value of
AUTH_USER_MODEL
in your settings.py withmyapp.User
(Custom User Model) likeAUTH_USER_MODEL = 'myapp.User'
.Recreate a fresh set of migrations using
python manage.py makemigrations
.Make a backup of your database.
Delete all entries from
django_migrations
table.Fake-apply the new set of migrations using
python manage.py migrate --fake
.Optional: Set
db_table="your_custom_table"
or remove it altogether.Make other changes to the custom model, generate migrations, apply them.
Solution: alternative way
You can take a different approach rather than overriding you auth.User model. You can define a new model(lets say Profile), and put your relevant fields there. Then, make a OneToOne
relation with auth.User like this:
class Profile(models.Model):
user = models.OneToOneField(User)
some_field = models.CharField(max_length=255, null=True, blank=True, default=None)
You can use post_save signals to create a profile automatically every time a User is created.
from django.dispatch import receiver
from django.core.signals import post_save
from django.contrib.auth.models import User
@receiver(post_save, sender=User)
def create_user_profile(sender, instance=None, created=None, **kwargs):
if created:
Profile.objects.create(user=instance)
You can use this easily in python:
user = User.objects.first()
user.profile.some_field # Thus you get value of some field from Profile
# OR
profile = Profile.objects.first()
user = profile.user # Thus you get auth.User
Or in template:
{{ user.profile.some_field }}
FYI: this process was mentioned in the django documentation as well.
For future projects
For future projects, you should use your CustomUser model from the beginning. It will reduce a lot of hassle when it comes to customizing User.
In conclusion
To Be Honest, this an old problem and there is no good way to resolve it(at least not in Django 2.1). Hopefully in future releases, it will be fixed.
Last updated: Feb 15, 2025
Thanks i was been struggling with this for some months, maybe you should be more specific with the number 1 of the HardWay of how to create an identical auth.User i just get the code from AbstractUser i just test on my development enviroment and works fine.
Okay, I will update the post accordingly.
Hi Ruddra, I’m struggling with this exact problem. Might you be able to help? https://stackoverflow.com/questions/57453469/trying-to-extend-base-user-model-mid-project-and-getting-unique-constraint-error.
I’m unsure how to design the ‘views’ for this solution. My current view saves the form inputs to the default User model and cannot get it to save to the new model. I also hit this ‘uniqueconstraint’ problem.
Thank you for this post. My query was that if we drop all the default tables created by Django’s makemigration command, will it affect the execution of the API catastrophically or can be managed with those tables. The reason is, those tables are considered to be Junk data. Kindly guide.
It shouldn’t affect if you are following this procedure. But before doing anything, please make a backup of your database.