Ved-форум поддержки
Программирование => Django => Тема начата: AdminUser от Мая 11, 2019, 10:47:30 am
-
Всем привет. Ничего не предвещало беды. Создал модели для диалога в новом файле подпапки 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)
Вот только не пойму, как и где правильно надо его вызвать
-
Трек ошибки указывает сначала на \django\contrib\auth\admin.py", line 7, затем на какую-то форму в \django\contrib\auth\forms.py", line 22..., затем на вызов get_user_model.
Т.е. непосредственно связано с админкой
Но удаление admin.py и django.contrib.admin из INSTALLED_APPS ничего не дало
-
Прежде, чем удалять, пройдитесь по треку
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
-
Спасибо, начал искать. И мне уже казалось, что ошибка происходит при вызове 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>. Пока уперся в него, не пойму где искать
-
Посмотрите через
print app_config.__class__
-
Нашел у себя в корне проекта 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.
Вас ис дас?
-
Попробуйте вставить в import_models класса AppConfig
traceback.print_stack()
И проследите каждый стек
-
Ура. Это было невероятное приключение... Короче, ошибку победил, удалив файл __init__.py из папки models. Причиной была следующая структура проекта:
models
__init__.py
models.py
Видимо, так делать нельзя. Надо делать либо все в models.py, либо все засовывать в папку с __init__.py:
models
__init__.py
models.py