Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AUTH_USER_MODEL refers to model 'accounts.User' that has not been installed

Tags:

python

django

I'm using a custom user model, extended with AbstractUser. Here's my models.py:

    # -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.forms import UserCreationForm

from django import forms

# Create your models here.
class User(AbstractUser):
    pass

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
    last_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
    email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )
enter code here

So when I try to run the development server, or migrate the database, it returns this error:

Traceback (most recent call last):
  File "./manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute
    django.setup()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/shivbhatia/Desktop/WishList/accounts/models.py", line 6, in <module>
    from django.contrib.auth.forms import UserCreationForm
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/forms.py", line 22, in <module>
    UserModel = get_user_model()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 198, in get_user_model
    "AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'accounts.User' that has not been installed

Here's my settings.py:

"""
Django settings for WishList project.

Generated by 'django-admin startproject' using Django 1.11.5.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = secret key goes here

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

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

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'WishList.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'WishList.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

AUTH_USER_MODEL = 'accounts.User'


# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Kolkata'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'

LOGIN_REDIRECT_URL = '/lists/'
LOGOUT_REDIRECT_URL = '/lists/'

I'm new to django, and I'm struggling to understand the user authentication systems.

I had to use the custom user extension because my user has to have a friends field, but I kept running into these kinds of problems. I have installed my accounts app in settings.py, but I get the sense I've missed a step. Why isn't it working?

like image 734
Shiv Bhatia Avatar asked Jan 03 '18 12:01

Shiv Bhatia


4 Answers

I suspect the problem is one of dependencies. You are importing UserCreationForm at the top of your accounts.models file, where it in turn tries to get the user model - but the rest of that models file has not yet been processed, so User is not defined.

You can easily solve this by following recommended practice and moving the form import and definition into a separate forms.py file.

like image 183
Daniel Roseman Avatar answered Nov 12 '22 18:11

Daniel Roseman


I had the same error when I tried to get the auth user by writing: User = get_user_model() at the top of my models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth import get_user_model

User = get_user_model()

class User(AbstractUser):
    is_official = models.BooleanField('official status', default=False)
    is_distro = models.BooleanField('distro status', default=False)
    is_subscriber = models.BooleanField('subscriber status', default=False)

I was able to resolve it by moving the User = get_user_model() below the User model definition, which makes sense as the get_user_model() getting called at the top of the User model definition meant it was referencing a model that doesn't exist yet. Here is the code layout that worked:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth import get_user_model

class User(AbstractUser):
    is_official = models.BooleanField('official status', default=False)
    is_distro = models.BooleanField('distro status', default=False)
    is_subscriber = models.BooleanField('subscriber status', default=False)

    def __str__(self):
        return self.username

User = get_user_model()

You may not have this exact layout but I guess the main point is To Not Reference A Model Before Its Definition In The Same File, This Is Why Import Statements Come At The Top.

like image 20
xodeeq Avatar answered Nov 12 '22 17:11

xodeeq


To better understand the issue, I'll illustrate how I solved this problem. For me moving one of the import statement (which internally used the User model) from the top of the file and placing it after the User model is defined fixed the issue

from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.db.models.signals import post_save
from rest_framework.authtoken.models import Token
from .utils import generate_token, send_email, generate_id



class User(AbstractUser):
    """User model."""

    username   = None
    email      = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

#### Moved the import statement here so that the issue is solved.
#### This function internally used User model which is only defined right above this.
from meter.tasks import apigeePipeline

def post_save_user_receiver(sender, instance, created, *args, **kwargs):
    if created:
        print("***********USer created**********")
        token = Token.objects.create(user=instance)
        send_email(instance.email, token.key)
        apigeePipeline(instance)


post_save.connect(post_save_user_receiver, sender=User)
like image 20
adam shamsudeen Avatar answered Nov 12 '22 16:11

adam shamsudeen


For me it worked when I tried shifting the position of the app in INSTALLED_APPS.

like image 1
subodhk Avatar answered Nov 12 '22 16:11

subodhk