Can't satisfy Django configuration for AUTH_USER_MODEL setting

115 Views Asked by At

I use Django Rest Framework and have a AbstractUser that I have inherited to create my user :

file : Project/NovalixExpedition/models/NovalixUserModel

from NovalixBackend.models.AddressModel import Address
from NovalixBackend.models.RoleModel import Role
from django.contrib.auth.models import AbstractUser

class NovalixUser(AbstractUser):
    id_novalix_user = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=100, blank=False, default='')
    last_name = models.CharField(max_length=100, blank=False, default='')
    email = models.CharField(max_length=100, blank=False, default='')
    phone_number = models.IntegerField(blank=False, default='')
    deleted = models.BooleanField(default=False)
    id_role = models.ManyToManyField(Role)
    current_address = models.ForeignKey(Address, on_delete=models.DO_NOTHING)

    class Meta:
        db_table = 'novalix_user'

It's located in a folder like so :

Project
|- manage.py
|
|- NovalixBackend
   |
   |- models
   |  |- __init__.py
   |  |- NovalixUserModel
   |
   |- settings.py

And I'm attempting to set it as my base model for django integrated authentication by setting the variable AUTH_USER_MODEL.

Step 1 - Naïve approach

However when I simply try in settings.py :

AUTH_USER_MODEL = 'NovalixBackend.models.NovalixUserModel.NovalixUser'

Result : AUTH_USER_MODEL must be of the form 'app_label.model_name

Step 2 - Follow the error indication

So I try to follow the recommendation :

AUTH_USER_MODEL = 'NovalixBackend.NovalixUser'

Result : django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'NovalixBackend.NovalixUser' that has not been installed

Of course since there's no module installed with this module name / path.

Step 3 - Follow the next django indication

I can try to install it then :

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'rest_framework',
    'rest_framework.authtoken',
    'corsheaders',

    'NovalixBackend.models',
    'django.contrib.admin',
    'drf_yasg',
    'NovalixBackend.NovalixUser'
]

AUTH_USER_MODEL = 'NovalixBackend.NovalixUser'

Result : ImportError: Module 'NovalixBackend' does not contain a 'NovalixUser' class.

Again, logical since no module exist in my code that would fulfill this module description.

Step 4.1 - I can try to fill the correct path and try to get the module in AUTH_USER_MODEL

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'rest_framework',
    'rest_framework.authtoken',
    'corsheaders',

    'NovalixBackend.models',
    'django.contrib.admin',
    'drf_yasg',
    'NovalixBackend.models.NovalixUserModel.NovalixUser'
]

AUTH_USER_MODEL = 'NovalixBackend.NovalixUser'

Result : django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

Yes I read about that in som eother issues, it's because I'm in settings, trying to configure stuff and I call a specific models right away.

I doubt this configuration would have worked anyway. So I can try something else :

Step 4.2 - I will make NovalixBackend.NovalixUser available as its own import in the module

So I add a init.py in the Project folder, here :

Project
|- manage.py
|
|- NovalixExpedition
   |- __init__.py <---- HERE
   |- models
   |  |- __init__.py 
   |  |- NovalixUserModel
   |
   |- settings.py

and inside I write :

from .models.NovalixUserModel import NovalixUser

without changing the settings.py (same as 4.1)

Result : django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

Same as before.

Step 4.3 - I'll try to make the models simpler

So I add a init.py in the Project folder, here :

Project
|- manage.py
|
|- NovalixExpedition
   |- models.py <---- HERE
   |- models
   |  |- __init__.py 
   |  |- NovalixUserModel
   |
   |- settings.py

and inside the new models.py file, I copy/paste the NovalixUserClass. so : Project/NovalixExpedition/models/NovalixUserModel and Project/NovalixExpedition/models.py have the exact same content. The file settings.py still have the line AUTH_USER_MODEL = "NovalixBackend.NovalixUser"

Result : django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'NovalixBackend.NovalixUser' that has not been installed

Problem

So I can't use a relative path for AUTH_USER_MODEL, but I can't import it a module for my project either. I'm then utterly stuck. And nothing online points to any resolution of this redundant cycle.

Note : The behaviour doesn't change by extending 'User' instead.

Annex :

Complete errors : django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'NovalixBackend.NovalixUser' that has not been installed

is

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\apps\config.py", line 268, in get_model
    return self.models[model_name.lower()]
KeyError: 'novalixuser'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\contrib\auth\__init__.py", line 160, in get_user_model
    return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\apps\registry.py", line 211, in get_model
    return app_config.get_model(model_name, require_ready=require_ready)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\apps\config.py", line 270, in get_model
    raise LookupError(
LookupError: App 'NovalixBackend' doesn't have a 'NovalixUser' model.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\aweisser\Miniconda3\envs\NovalixBoilerplate\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\Users\aweisser\Miniconda3\envs\NovalixBoilerplate\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\core\management\commands\runserver.py", line 110, in inner_run
    autoreload.raise_last_exception()
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\utils\autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\core\management\__init__.py", line 375, in execute
    autoreload.check_errors(django.setup)()
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\apps\registry.py", line 122, in populate
    app_config.ready()
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\contrib\auth\apps.py", line 23, in ready
    last_login_field = getattr(get_user_model(), 'last_login', None)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\contrib\auth\__init__.py", line 164, in get_user_model
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'NovalixBackend.NovalixUser' that has not been installed

AUTH_USER_MODEL must be of the form 'app_label.model_name is

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\utils.py", line 15, in make_model_tuple
    app_label, model_name = model.split(".")
ValueError: too many values to unpack (expected 2)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\aweisser\Miniconda3\envs\NovalixBoilerplate\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\Users\aweisser\Miniconda3\envs\NovalixBoilerplate\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\core\management\commands\runserver.py", line 110, in inner_run
    autoreload.raise_last_exception()
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\utils\autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\core\management\__init__.py", line 375, in execute
    autoreload.check_errors(django.setup)()
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\apps\registry.py", line 114, in populate
    app_config.import_models()
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\apps\config.py", line 301, in import_models
    self.models_module = import_module(models_module_name)
  File "C:\Users\aweisser\Miniconda3\envs\NovalixBoilerplate\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "C:\Users\aweisser\Miniconda3\envs\NovalixBoilerplate\lib\site-packages\rest_framework\authtoken\models.py", line 9, in <module>
    class Token(models.Model):
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\base.py", line 161, in __new__
    new_class.add_to_class(obj_name, obj)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\base.py", line 326, in add_to_class
    value.contribute_to_class(cls, name)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\fields\related.py", line 747, in contribute_to_class
    super().contribute_to_class(cls, name, private_only=private_only, **kwargs)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\fields\related.py", line 318, in contribute_to_class
    lazy_related_operation(resolve_related_class, cls, self.remote_field.model, field=self)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\fields\related.py", line 80, in lazy_related_operation
    return apps.lazy_model_operation(partial(function, **kwargs), *model_keys)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\fields\related.py", line 78, in <genexpr>
    model_keys = (make_model_tuple(m) for m in models)
  File "C:\Users\aweisser\AppData\Roaming\Python\Python39\site-packages\django\db\models\utils.py", line 22, in make_model_tuple
    raise ValueError(
ValueError: Invalid model reference 'NovalixBackend.models.NovalixUser'. String model references must be of the form 'app_label.ModelName'.
2

There are 2 best solutions below

7
Tanveer On
from NovalixBackend.models.AddressModel import Address
from NovalixBackend.models.RoleModel import Role
from django.contrib.auth.models import AbstractUser

class NovalixUser(AbstractUser):
    id_novalix_user = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=100, blank=False, default='')
    last_name = models.CharField(max_length=100, blank=False, default='')
    email = models.CharField(max_length=100, blank=False, default='')
    phone_number = models.IntegerField(blank=False, default='')
    deleted = models.BooleanField(default=False)
    id_role = models.ManyToManyField(Role)
    current_address = models.ForeignKey(Address, on_delete=models.DO_NOTHING)

    EMAIL_FIELD = "email"
    USERNAME_FIELD = "username"
    REQUIRED_FIELDS = ["email"]


    class Meta:
        db_table = 'novalix_user'

Abstract User comes from built-in and import from django models whether you extend from it or use it as same as django provide

1
jayjaychukwu On

The name of the app is "NovalixExpedition", right?

If no, the project structure seems like a problem.

Your apps, manage.py file and the folder that holds settings.py, wsgi.py etc should all be in the same directory.

In your settings.py file, do this:

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',

    #Third-party apps
    'rest_framework',
    'rest_framework.authtoken',
    'corsheaders',
    'drf_yasg',

    #Local apps
    '{app_that_has_models.py_with_user_model}',

]

AUTH_USER_MODEL = '{app_that_has_models.py_with_user_model}.NovalixUser'

Ensure that the app has a models.py file in it with the User model, that's all. It should work.