Автор Тема: auth_user_model refers to model main.profile that has not been installed  (Прочитано 4290 раз)

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Всем привет. Ничего не предвещало беды. Создал модели для диалога в новом файле подпапки models моего проекта:

# -*- coding: utf-8 -*-

from django.db import models

from django.utils import timezone
from main.models import Profile

class Dialogue(models.Model):
    Partakers = models.ManyToManyField(Profile)

class Message(models.Model):
    Sender = models.ForeignKey(Profile)
    Time = models.DateTimeField(default=timezone.now)
    Content = models.TextField()

    Target = models.ForeignKey(Dialogue) 

Рабочий день закончился. Ушел домой. И на следующее утри получил ошибку из заголовка. Созданные модели закомментировал. Ошибка никуда не ушла.

И, как обычно, по ошибке в джанго ничего не понятно. Трэк даже ни на один пользовательский файл не указывает:

Цитата:
(hello) D:\django\site\hello>d: & cd D:\django\hello\Scripts & activate.bat & cd
 D:\django\site\hello & python manage.py runserver
Unhandled exception in thread started by <function wrapper at 0x02B93B70>
Traceback (most recent call last):
  File "D:\django\hello\lib\site-packages\django\utils\autoreload.py", line 228,
 in wrapper
    fn(*args, **kwargs)
  File "D:\django\hello\lib\site-packages\django\core\management\commands\runser
ver.py", line 116, in inner_run
    autoreload.raise_last_exception()
  File "D:\django\hello\lib\site-packages\django\utils\autoreload.py", line 251,
 in raise_last_exception
    six.reraise(*_exception)
  File "D:\django\hello\lib\site-packages\django\utils\autoreload.py", line 228,
 in wrapper
    fn(*args, **kwargs)
  File "D:\django\hello\lib\site-packages\django\__init__.py", line 27, in setup

    apps.populate(settings.INSTALLED_APPS)
  File "D:\django\hello\lib\site-packages\django\apps\registry.py", line 116, in
 populate
    app_config.ready()
  File "D:\django\hello\lib\site-packages\django\contrib\admin\apps.py", line 23
, in ready
    self.module.autodiscover()
  File "D:\django\hello\lib\site-packages\django\contrib\admin\__init__.py", lin
e 26, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "D:\django\hello\lib\site-packages\django\utils\module_loading.py", line
50, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "D:\django\hello\lib\site-packages\django\contrib\auth\admin.py", line 7,
 in <module>
    from django.contrib.auth.forms import (
  File "D:\django\hello\lib\site-packages\django\contrib\auth\forms.py", line 22
, in <module>
    UserModel = get_user_model()
  File "D:\django\hello\lib\site-packages\django\contrib\auth\__init__.py", line
 199, in get_user_model
    "AUTH_USER_MODEL refers to model '%s' that has not been installed" % setting
s.AUTH_USER_MODEL
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'ma
in.Profile' that has not been installed

Предполагаю, что за заполнение self.models отвечает import_models того же объекта:

    def import_models(self):
        # Dictionary of models for this app, primarily maintained in the
        # 'all_models' attribute of the Apps this AppConfig is attached to.

        if module_has_submodule(self.module, MODELS_MODULE_NAME):
            models_module_name = '%s.%s' % (self.name, MODELS_MODULE_NAME)
            self.models_module = import_module(models_module_name)

Вот только не пойму, как и где правильно надо его вызвать
« Последнее редактирование: Мая 11, 2019, 05:55:40 pm от AdminUser »

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #1 : Мая 11, 2019, 12:13:03 pm »
Трек ошибки указывает сначала на \django\contrib\auth\admin.py", line 7, затем на какую-то форму в \django\contrib\auth\forms.py", line 22..., затем на вызов get_user_model. 

Т.е. непосредственно связано с админкой

Но удаление admin.py и django.contrib.admin из INSTALLED_APPS ничего не дало
« Последнее редактирование: Мая 11, 2019, 01:16:22 pm от AdminUser »

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #2 : Мая 11, 2019, 01:32:02 pm »
Прежде, чем удалять, пройдитесь по треку

7-я строка в admin.py:

from django.contrib.auth.forms import (
    AdminPasswordChangeForm, UserChangeForm, UserCreationForm,
)

22-я строка в forms.py:

UserModel = get_user_model()
Код get_user_model:

def get_user_model():
    """
    Returns the User model that is active in this project.
    """
    try:
        return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
    except ValueError:
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
    except LookupError:
        raise ImproperlyConfigured(
            "AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
        )

У вас ошибка в django_apps.get_model. Переходим к ней:

    def get_model(self, app_label, model_name=None, require_ready=True):

        if require_ready:
            self.check_models_ready()
        else:
            self.check_apps_ready()

        if model_name is None:
            app_label, model_name = app_label.split('.')

        app_config = self.get_app_config(app_label)

        if not require_ready and app_config.models is None:
            app_config.import_models()

        return app_config.get_model(model_name, require_ready=require_ready)

Вот здесь дебажьте. Ваш объект app_config
« Последнее редактирование: Мая 11, 2019, 01:48:47 pm от AdminUser »

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #3 : Мая 11, 2019, 01:50:49 pm »
Спасибо, начал искать. И мне уже казалось, что ошибка происходит при вызове get_app_config:

    def get_app_config(self, app_label):
        """
        Imports applications and returns an app config for the given label.
        Raises LookupError if no application exists with this label.
        """
        self.check_apps_ready()
        try:
            return self.app_configs[app_label]
        except KeyError:
            message = "No installed app with label '%s'." % app_label
            for app_config in self.get_app_configs():
                if app_config.name == app_label:
                    message += " Did you mean '%s'?" % app_config.label
                    break
            raise LookupError(message)

Видимо, при обращении к очередному элементу словаря app_configs:

[<AuthConfig: auth>, <ContentTypesConfig: contenttypes>, <SessionsConfig: sessio
ns>, <MessagesConfig: messages>, <StaticFilesConfig: staticfiles>, <MainConfig:
main>, <AdminConfig: admin>, <DebugToolbarConfig: debug_toolbar>]

app_configs - это словарь, который содержит приложения из INSTALLED_APPS моего settings.py

Но как она возникает, вопрос. Код нормально выполняется до последней строки get_model:

        return app_config.get_model(model_name, require_ready=require_ready)
В качестве параметров в нее передается model_name = 'Profile' и require_ready=False. Ошибка возникает на нем, но это не рекурсия. Метод app_config.get_model не принадлежит registry.App, в котором находится вызываемый get_model. Он находится где-то в объекте класса <MainConfig.main>. Пока уперся в него, не пойму где искать
« Последнее редактирование: Мая 11, 2019, 02:36:32 pm от AdminUser »

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #4 : Мая 11, 2019, 02:40:51 pm »
Посмотрите через

print app_config.__class__

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #5 : Мая 11, 2019, 02:46:29 pm »
Нашел у себя в корне проекта apps.py, в котором я определил этот MainConfig

class MainConfig(AppConfig):
    name = 'main'
    verbose_name=u'Главное приложение'

а так же в __init__.py проекта:

default_app_config = 'main.apps.MainConfig'
Вот только для чего, я уже не помню... Короче, удалил. Но ошибка осталась, правда на другом приложении. Теперь вместо MainConfig ругается на AppConfig

Короче, таким образом я понял, что get_model вызывается из AppConfig. Вот он:

    def get_model(self, model_name, require_ready=True):
        """
        Returns the model with the given case-insensitive model_name.

        Raises LookupError if no model exists with this name.
        """
        if require_ready:
            self.apps.check_models_ready()
        else:
            self.apps.check_apps_ready()
        try:
            return self.models[model_name.lower()]
        except KeyError:
            raise LookupError(
                "App '%s' doesn't have a '%s' model." % (self.label, model_name))

Так вот.. self.models - оказывается, у меня пустой..

Поставил ловушку на import_models. Видимо, через нее заполняется self.models:

    def import_models(self):
        # Dictionary of models for this app, primarily maintained in the
        # 'all_models' attribute of the Apps this AppConfig is attached to.

        self.models = self.apps.all_models[self.label]

        print self.label + ' >> {}'.format(self.apps.all_models[self.label])

        if module_has_submodule(self.module, MODELS_MODULE_NAME):
            models_module_name = '%s.%s' % (self.name, MODELS_MODULE_NAME)
            self.models_module = import_module(models_module_name)

Для всех приложений кроме contenttypes self.apps.all_models[self.label] возвращает пустой OrderedDict.
Вас ис дас?
« Последнее редактирование: Мая 12, 2019, 12:33:42 pm от AdminUser »

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #6 : Мая 12, 2019, 12:28:52 pm »
Попробуйте вставить в import_models класса AppConfig

traceback.print_stack()
И проследите каждый стек

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: auth_user_model refers to model main.profile that has not been installed
« Ответ #7 : Мая 12, 2019, 12:59:11 pm »
Ура. Это было невероятное приключение... Короче, ошибку победил, удалив файл __init__.py из папки models. Причиной была следующая структура проекта:

models
     __init__.py
models.py

Видимо, так делать нельзя. Надо делать либо все в models.py, либо все засовывать в папку с __init__.py:

models
     __init__.py
     models.py