Django - Setting AUTH_USER_MODEL

django authentication
django-login with email or username
django permissions
django user profile
django rest framework custom user model
django custom login page
django authentication middleware
how to create a custom django user model

I have created a Django project named Backend and in that, I have created an app called Tool.

Now, I have created a User model by inheriting the AbstractUser model and I have created 2 accounts using this model.

class User(AbstractUser):
    is_student = models.BooleanField(default=False)
    is_mentor  = models.BooleanField(default=False)

class Student(models.Model):
    user       = models.OneToOneField(User, on_delete=models.CASCADE)
    college    = models.CharField(max_length=100)
    ...

class Mentor(models.Model):
    user       = models.OneToOneField(User, on_delete=models.CASCADE)
    ...

I have updated the settings.py in Backend folder in this way:

AUTH_USER_MODEL = 'Tool.User'

After makemigrations and migrate, I am getting the following error:

ValueError: Related model 'Tool.User' cannot be resolved


Traceback:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\core\management\base.py", line 353, in execute
    output = self.handle(*args, **options)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\core\management\base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\core\management\commands\migrate.py", line 203, in handle
    fake_initial=fake_initial,
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\migrations\migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\migrations\operations\models.py", line 91, in database_forwards
    schema_editor.create_model(model)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\backends\base\schema.py", line 263, in create_model
    definition, extra_params = self.column_sql(model, field)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\backends\base\schema.py", line 157, in column_sql
    db_params = field.db_parameters(connection=self.connection)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\models\fields\related.py", line 966, in db_parameters
    return {"type": self.db_type(connection), "check": self.db_check(connection)}
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\models\fields\related.py", line 963, in db_type
    return self.target_field.rel_db_type(connection=connection)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\models\fields\related.py", line 878, in target_field
    return self.foreign_related_fields[0]
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\models\fields\related.py", line 632, in foreign_related_fields
    return tuple(rhs_field for lhs_field, rhs_field in self.related_fields if rhs_field)
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\models\fields\related.py", line 619, in related_fields
    self._related_fields = self.resolve_related_fields()
  File "C:\Users\Sreekar Mouli\Documents\Mini Project\Backend\venv\lib\site-packages\django\db\models\fields\related.py", line 604, in resolve_related_fields
    raise ValueError('Related model %r cannot be resolved' % self.remote_field.model)

I have cleared all the previous migrations, dropped the db and re-created it. When I run makemigrations and migrate, it worked fine.

Seems like there were some issues with previous migrations. But, it's confusing and wierd that it was showing this error.

ValueError: Related model 'Tool.User' cannot be resolved

Settings | Django documentation, Using settings.AUTH_USER_MODEL will delay the retrieval of the actual model class until all apps are loaded. get_user_model will attempt to  get_user_model () Instead of referring to User directly, you should reference the user model using django.contrib.auth.get_user_model (). This method will return the currently active User model – the custom User model if one is specified, or User otherwise. When you define a foreign key or many-to-many relations to the User model, you should specify the custom model using the AUTH_USER_MODEL setting.

I think you are facing issues when changing the USER model in middle of project. This change can't be done automatically, and needs to be done manually. As per this ticket, you can follow these steps to manually migrate user model:

  1. Create a custom user model identical to auth.User, call it User (so many-to-many tables keep the same name) and set db_table='auth_user' (so it uses the same table)
  2. Throw away all your migrations
  3. Recreate a fresh set of migrations
  4. make a backup of your database
  5. Truncate the django_migrations table
  6. Fake-apply the new set of migrations
  7. Unset db_table, make other changes to the custom model, generate migrations, apply them

If you have the luxury to delete the DB then you can follow @SreekarMouli's answer.

Django using get_user_model vs settings.AUTH_USER_MODEL , settings.py AUTH_USER_MODEL = `users.CustomUser`. In our Blog models.py file the code would look like this: from django.conf import  Using settings we pass the AUTH_USER_MODEL as a string into our model. Option 3: get_user_model. A third way to access the user model is via get_user_model. Up until the release of Django 1.11, get_user_model was not called at import time--meaning it would not always work correctly--however that has since been changed. It is therefore safe to use.

What is your app name? The letter size is important

aplication "Tool", model "User"

settings.py

INSTALLED_APPS = (
    ...
    "Tool",
)
AUTH_USER_MODEL = 'Tool.User'

and in case you are going to import user to other files, better do it this way

views.py

from django.contrib.auth import get_user_model
User = get_user_model()

And try to make new migrations. If you do not want to add depenses.

Django settings | Django documentation, from django.conf import settings from django.db import models class model, you should specify the custom model using the AUTH_USER_MODEL setting. The default Django's user model is django.contrib.auth.model.User and it stores username, first_name, last_name, email and some other meta data. The best way to add more details is to define a new model with a OneToOneField related to the User model. For example let us define model called Profile which can store some extra details of the user.

General Django Troubleshooting Techniques, At Caktus, when Django first added support for a custom user model, we users to INSTALLED_APPS and set AUTH_USER_MODEL = 'users. Add the new app to our INSTALLED_APPS setting and add a new setting for AUTH_USER_MODEL. This tells Django that instead of using the default User model look in our app users for the model called CustomUser and use that instead everywhere in our project.

django.conf.settings.AUTH_USER_MODEL Python Example, Settings. Add the following line to the settings.py file so that Django knows to use the new User class: AUTH_USER_MODEL  Django provides safe mechanisms for accessing the User model as needed. Referencing the User model (without using the actual model class) When you want to reference the User model without importing it, such as in defining foreign key relationships, you should use the AUTH_USER_MODEL setting:

Django Best Practices: Referencing the User Model, Custom user model for django >=1.11 with support for multiple user types. Set your AUTH_USER_MODEL setting to use users.User: AUTH_USER_MODEL  You cannot change the AUTH_USER_MODEL setting during the lifetime of a project (i.e. once you have made and migrated models that depend on it) without serious effort. It is intended to be set at the project start, and the model it refers to must be available in the first migration of the app that it lives in.

Comments
  • can you please share your full stacktrace?
  • also can you share your related migration files?
  • Have you installed your application (list in INSTALLED_APPS)?
  • @ruddra, I have added the stacktrace. And, yes I have listed my app in INSTALLED_APPS @vishes_shell.
  • My app's name is Tool, I have mentioned that in the first line. INSTALLED_APPS = ("Tool", ) AUTH_USER_MODEL='Tool.User'. This is how my settings.py is.
  • better name applications with small letters :) Tool looks like a class name. This is not necessarily but makes easier code maintaining
  • Ya, I will work on those namings. The error still exists!!
  • looks like migrations problem. Can u return to previous migration? and make new again
  • Seems like migrations was the problem. Thanks for the help.