Chase Roberts
Chase Roberts

Reputation: 9376

AUTH_USER_MODEL refers to model that has not been installed

I am getting an error

ImproperlyConfigured at /admin/
AUTH_USER_MODEL refers to model 'ledger.User' that has not been installed

I am only getting it on my production server. Not when I run things via localhost. First it was only when I was making a certain request. Then I thought my database must be out of sync so I deleted all the tables and then ran manage.py syncdb. Now, it seems to have propogated and even going to the admin throws the error.

I have never seen this error before and can't figure out what the deal is. I have defined the AUTH_USER_MODEL in settings.py:

...
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'ledger',
    'extension',
    'plugin',
    'social.apps.django_app.default',
)

AUTH_USER_MODEL = 'ledger.User'

...

models.py:

...
class User(AbstractUser):
    def __unicode__(self):
        return self.username
    balance = models.IntegerField(default=0)
    total_pledged = models.IntegerField(default=0)
    last_pledged = models.ForeignKey('Transaction', related_name='pledger', blank=True, null=True)
    extension_key = models.CharField(max_length=100, null=True, blank=True)
    plugin_key = models.CharField(max_length=100, null=True, blank=True)
    ghosted = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        print('saving')
        try:
            self.company.save()
        except:
            print('no company')
        super(User, self).save(*args, **kwargs)
...

Upvotes: 14

Views: 39709

Answers (12)

Duke Dougal
Duke Dougal

Reputation: 26336

I had this problem and it was solved by properly understanding how the Django filed are structured.

The instructions in tutorials are often different and confusing.

You need to understand that when you install Django, there are two key steps:

  1. Creating a project
  2. Creating an app (application)

Let's illustrate the problem by following the official Django tutorial:

https://docs.djangoproject.com/en/3.1/intro/tutorial01/

Step 1: create a new project:

django-admin startproject mysite

You will now find there is a directory called "mysite"

**Step 2: ** the tutorial says: To create your app, make sure you’re in the same directory as manage.py and type this command: which is the directory just created, so go to:

cd mysite

and if you ls then you will find in this directory is: a file named manage.py confusingly, another directory named mysite

Step 3: Now the tutorial says to create your django application:

python manage.py startapp polls

So now ls shows these files: manage.py
mysite
polls

Consufion has probably set in right now because all these files are under the mysite directory.

Step 4: If you want to use a custom user model, then the official advice is to do it right at the start of the project before doing any migrations.

OK, so edit mysite/settings.py and add the line:

AUTH_USER_MODEL = 'polls.User'   

and edit polls/models and add:

from django.db import models

# Create your models here.

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

** Step 5:** So now it should be OK to do the first migration, right?

python manage.py makemigrations

But SPLAT!

Traceback (most recent call last):
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/apps/registry.py", line 156, in get_app_config
    return self.app_configs[app_label]
KeyError: 'polls'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 157, in get_user_model
    return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/apps/registry.py", line 206, in get_model
    app_config = self.get_app_config(app_label)
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/apps/registry.py", line 163, in get_app_config
    raise LookupError(message)
LookupError: No installed app with label 'polls'.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
  File "manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/core/management/__init__.py", line 377, in execute
    django.setup()
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/contrib/admin/apps.py", line 24, in ready
    self.module.autodiscover()
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/utils/module_loading.py", line 47, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/contrib/auth/admin.py", line 6, in <module>
    from django.contrib.auth.forms import (
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/contrib/auth/forms.py", line 21, in <module>
    UserModel = get_user_model()
  File "/opt/theapp/venv3.8/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 161, in get_user_model
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'polls.User' that has not been installed
(venv3.8) ubuntu@ip-172-26-5-79:~/mysite$

There is the error: .ImproperlyConfigured: AUTH_USER_MODEL refers to model 'polls.User' that has not been installed

So we fix this by modifying mysite/settings.py from this:

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

to this:

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

Notice that the line you needed to add was "polls" which is the name of your Django application.

Now try again:

(venv3.8) ubuntu@ip-172-26-5-79:~/mysite$ python manage.py makemigrations
Migrations for 'polls':
  polls/migrations/0001_initial.py
    - Create model User
(venv3.8) ubuntu@ip-172-26-5-79:~/mysite$

Success!!!

So the point of this long story is to make it clear that Django MUST know where your Django application is. And the place that you tell Django that, is in INSTALLED_APPS in the settings.py file.

It's really confusing the difference between Django project and Django app and its made worse by the strange suggestion to create two directories with the same name.

Instead, to make things much more clear I suggest you suffix your Django project name with "project" and suffix your Django application name with "app" and don't give the top level directory the same name as the project.

Thus to set up a new project:

(venv3.8) ubuntu@ip-172-26-5-79:~$ mkdir container
(venv3.8) ubuntu@ip-172-26-5-79:~$ cd container/
(venv3.8) ubuntu@ip-172-26-5-79:~/container$ django-admin startproject myproject .
(venv3.8) ubuntu@ip-172-26-5-79:~/container$ ls
manage.py  myproject
(venv3.8) ubuntu@ip-172-26-5-79:~/container$ python manage.py startapp myapp
(venv3.8) ubuntu@ip-172-26-5-79:~/container$ ls -lah
total 20K
drwxrwxr-x  4 ubuntu ubuntu 4.0K Oct 27 05:30 .
drwxr-xr-x 11 ubuntu ubuntu 4.0K Oct 27 05:29 ..
-rwxrwx---  1 ubuntu ubuntu  665 Oct 27 05:30 manage.py
drwxrwxr-x  3 ubuntu ubuntu 4.0K Oct 27 05:30 myapp
drwxrwxr-x  3 ubuntu ubuntu 4.0K Oct 27 05:30 myproject
(venv3.8) ubuntu@ip-172-26-5-79:~/container$

It's now going to be much more clear to you when you are dealing with the Django site and when you are dealing with the Django project and you will no longer be confused by there being multiple directories of the same name.

Upvotes: 17

crazycoder65
crazycoder65

Reputation: 401

It looks like if you try to create a custom User Model halfway through a project, you may run into circular dependency errors due to Django model dependencies.

This is from the Django Official Docs:

Changing to a custom user model mid-project Changing AUTH_USER_MODEL after you’ve created database tables is significantly more difficult since it affects foreign keys and many-to-many relationships, for example.

This change can’t be done automatically and requires manually fixing your schema, moving your data from the old user table, and possibly manually reapplying some migrations. See #25313 for an outline of the steps.

Due to limitations of Django’s dynamic dependency feature for swappable models, the model referenced by AUTH_USER_MODEL must be created in the first migration of its app (usually called 0001_initial); otherwise, you’ll have dependency issues.

In addition, you may run into a CircularDependencyError when running your migrations as Django won’t be able to automatically break the dependency loop due to the dynamic dependency. If you see this error, you should break the loop by moving the models depended on by your user model into a second migration. (You can try making two normal models that have a ForeignKey to each other and seeing how makemigrations resolves that circular dependency if you want to see how it’s usually done.)

Their recommendation includes separating models defining your custom User model and those using it into separate migrations, with the User model defined in the first migration.

Upvotes: 0

okokokokokokokok
okokokokokokokok

Reputation: 33

I've had the same problem, but no answer here worked for me.

My issue was that my custom UserAdmin was in models.py but not in admin.py. Hope that helps!

I found the solution here : Django LookupError: App 'accounts' doesn't have a 'User' model

Link to the original answer: https://groups.google.com/g/django-users/c/pciwcW84DkQ/m/Z7W6KznlBwAJ

Upvotes: -1

M. Bagheri
M. Bagheri

Reputation: 11

In my case, the problem was that I had imported something that belonged to the default User model.

# my_app/models.py
from django.db import models
from django.contrib.auth.forms import (UserCreationForm, UserChangeForm)  # Problematic line
from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):
    pass

Both UserCreationForm and UserChangeForm actually have set model = User in their inner Meta class and can't be used with a custom user model. Once I removed that line, makemigrations (and other manage.py commands) worked with no problem.

I had forgot that I can't use User forms directly with a custom user model, and should rather subclass them and set model = CustomUser in their inner Meta class. For example:

class CustomUserCreationForm(UserCreationForm):
    class Meta(UserCreationForm.Meta):
        model = CustomUser

Upvotes: 0

ilteen
ilteen

Reputation: 3

I have tried all the answers above, made sure that everything was set up as described before, it still didn't work.

I'm running django in a docker container and don't have much experience with this. The solution for me was to simply rebuild (only) the django image with docker-compose up -d --no-deps --build django.

Upvotes: 0

Andrew
Andrew

Reputation: 8674

My issue was that my custom user model had an incorrect app_label manually applied to it in the Meta class. Only took me 3 hours to figure it out!

# project/settings.py
INSTALLED_APPS += [
    "project.random_app",
    "project.user_app",   # app containing the custom user model
]
AUTH_USER_MODEL = "user_app.MyUser"

And the error in the user model class app_label

# project/user_app/models.py
class MyUser(Model):
    class Meta:
        app_label = "WRONG"  # must match an app in `installed_apps`

I solved this by removing the app_label, since its not actually needed. You could also make it match the name of the app, but user_app.

In my case this was set due to trying to fix the same issue a while ago, getting it working, and then doing a reoganization before pushing.

Upvotes: 0

user1778743
user1778743

Reputation: 353

Using Django 3.1

My issue was very simple due to the fact that i was using development settings. which had info was missing for the installed apps for normal settings file

Upvotes: 0

anthonyjsaab
anthonyjsaab

Reputation: 56

In my case a circular import statement produced the error mentioned by OP. Here was my buggy code:

custom_auth_app/models.py

...
from custom_auth_app import views.py
...
class CustomUser(AbstractUser):
    ...

Meanwhile in custom_auth_app/views.py

from custom_auth_app import models
...
models.CustomUser.objects.all()

And as a second proof to my claim, I did not get an error after reordering statements in custom_auth_app/models.py

...
class CustomUser(AbstractUser):
    ...
from custom_auth_app import views.py # won't cause an error
...

Thus, this circular import prevented CustomUser from being loaded, and caused the error.

Upvotes: 3

Joshua
Joshua

Reputation: 314

I'm aware this is an old question but I struggled with this issue for two days before finding my mistake, which was failing to follow the models organization in the Django Models docs.

If you have the AUTH_USER_MODEL = '<app_name>.<user_model>' (e.g. 'ledger.User') correctly written, and you have your '<app_name>', (e.g. ledger), in your INSTALLED_APPS list, but you're still getting this error, it's possible that your <custom_user> model (e.g. User) is in the wrong place.

It needs to be defined in either the models.py file in the top level of your app directory:

  • <app_name>/models.py

OR in a models/ directory containing an __init__.py file that imports your model:

  • <app_name>/models/<arbitrary_name>.py AND there is an <app_name>/models/__init__.py that contains the line from .<arbitrary_name> import <custom_user>

Upvotes: 5

Elembivios
Elembivios

Reputation: 398

Don't have enough rep to comment on @Duke Dougal solution so i'm creating a new comment.

Had the same problem but none of the above solutions worked for me. Finally fixed it by moving my app (where I have my User model) to the very end of INSTALLED APPS (even after all of my other apps). So something like this:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'my_other_app_1',
'my_other_app_2',
'polls', # <-- App with my custom User model

]

Upvotes: 3

Abhishek Dalvi
Abhishek Dalvi

Reputation: 390

I know this is a very old question but I felt like sharing my discovery (of how stupid I can be!).

In my case, the issue was that my custom user model had abstract=True set in the Meta class (happens when you copy the base class code in order to override it :P).

Upvotes: 3

scum
scum

Reputation: 3212

This error can appear if any one of your other apps fails to load - even if it has nothing to do with the custom user model. In my case, I had the 'gcharts' app installed but needed to install the google-visualization-python library with it. Neither have anything to do with the user model, but django returned this error regardless.

The following should reveal the true root cause of your issue:

  • Comment out most of your apps in settings.py until django boots up.
  • Add apps back one at a time until you get an error

Upvotes: 2

Related Questions