'Django `LookupError: App 'accounts' doesn't have a 'User' model` causes AUTH_USER_MODEL fails with `accounts.User` has not been installed

I am trying to refactor an existing code base by creating new accounts app with new custom User model. When I try to do makemigrations, I get the following error:

Traceback (most recent call last):
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/apps/config.py", line 268, in get_model
    return self.models[model_name.lower()]
KeyError: 'user'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/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 "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/apps/registry.py", line 211, in get_model
    return app_config.get_model(model_name, require_ready=require_ready)
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/apps/config.py", line 270, in get_model
    raise LookupError(
LookupError: App 'accounts' doesn't have a 'User' model.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/dev/Projects/Foto-Dino/foto-dino/manage.py", line 22, in <module>
    main()
  File "/home/dev/Projects/Foto-Dino/foto-dino/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
    django.setup()
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/contrib/admin/apps.py", line 27, in ready
    self.module.autodiscover()
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/contrib/admin/__init__.py", line 24, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/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.9/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 "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/contrib/auth/admin.py", line 6, in <module>
    from django.contrib.auth.forms import (
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/site-packages/django/contrib/auth/forms.py", line 21, in <module>
    UserModel = get_user_model()
  File "/home/dev/.virtualenvs/foto-dino/lib/python3.9/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 'accounts.User' that has not been installed

I know this question has been asked many times before, and I have looked through many previous posts, but none of the solutions worked. The main one that kept coming up was the adding accounts to INSTALLED_APPS and setting AUTH_USER_MODEL to "accounts.User". I tried deleting all migrations folders and deleted the database file. The accounts.model.py looks like this:

from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import ugettext_lazy as _
from django.db import models
from rest_framework.authtoken.models import Token
from django.contrib.auth.hashers import make_password
from utils.uid import uidgen

class UserManager(BaseUserManager):
    def create_user(self, email, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        if not email:
            raise ValueError(_("The Email must be set"))
        email = self.normalize_email(email)
        password = make_password(password)
        user = self.model(email=email, **extra_fields)
        user.save()
        if user.role == User.Roles.SECRETARY:
            user.is_staff = True
        Token.objects.create(user=user)
        return user

    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)
        extra_fields.setdefault("is_active", True)

        admin_user = self.create_user(email, password, **extra_fields)
        admin_user.is_staff = True
        admin_user.is_superuser = True
        admin_user.save()
        return admin_user


class User(AbstractBaseUser, PermissionsMixin):
    id = models.CharField(
        max_length=8, unique=True, primary_key=True, default=uidgen, editable=False
    )
    first_name = models.CharField(_("First Name"), max_length=30, null=False)
    last_name = models.CharField(_("Last Name"), max_length=30, null=True, blank=True)
    email = models.EmailField(
        verbose_name="Email", max_length=255, unique=True, null=False
    )
    ...
    # more fields here
    ...

    class Meta:
        abstract = True

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

    objects = UserManager()


class Client(User):
    # client details here
    pass

In Settings.py I have:


...
# settings above
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "social_django",
    "accounts",
    # "admin_portal",
    # "main",
    # "photographer",
    # "photoshoper",
    # "printer",
    # "secretary",
    # "phonenumber_field",
]
...
# more settings here
...
AUTH_USER_MODEL = "accounts.User"

I even tried adding the following to my accounts.admin.py:

from django.contrib import admin
from accounts.models import User

admin.sites.register(User)

The folder structure for accounts:

accounts
├── views.py
├── tests_
│   ├── models.py
│   ├── __init__.py
│   └── baker_recipes.py
├── models.py
├── migrations
│   └── __init__.py
├── __init__.py
├── apps.py
└── admin.py


Solution 1:[1]

It's because you've set the User Model to Abstract. Meaning Django won't create a table for that model upon migration. That is why you have that error. You can either remove The abstract = True from the Meta class or create a NewUser class that will inherit from User model and you now set AUTH_USER_MODEL = accounts.NewUser.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kevin Dongmo F.