(django)为什么在将应用程序添加到INSTALLED_APPS时会出现错误,而不是在导入时出错?

时间:2017-04-30 15:17:53

标签: django python-import

我用抽象类,一些utils函数,我的常用模板标签等编写了一个应用程序。

有些人,我看到了推荐的方法将这些东西用于可重用的应用程序。 (它们都彼此相关。)为什么不呢?这似乎是个好主意。所以我把这些东西作为应用程序的一部分。由于该应用程序没有网址,视图而不是正常的结构,因此它更像是一个python模块。 (但它需要django。)

当我以正常方式导入此应用程序(在文件顶部使用import myapp)时,它可以正常工作。

寻找我在官方django教程第8部分中看到的最佳实践,建议在INSTALLED_APPS settings.py中导入应用。由于我将我的utils模块作为应用程序,我想我可以在INSTALLED_APPS添加一行。就像这样:myapp.apps.MyappConfig

我的项目结构:

project
|-... [multiple normal apps]
|-myapp [which is my utils app]
|-project [the inner folder]
|-... [some other stuff]

正如您所看到的,myapp,utils应用程序仍然是项目的一部分(并且还没有成为可重用的应用程序。)

但是当我将该行添加到INSTALLED_APPS时,我得到以下追溯:

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0xb6356adc>
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/django/utils/autoreload.py", line 227, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/runserver.py", line 117, in inner_run
    autoreload.raise_last_exception()
  File "/usr/local/lib/python3.5/dist-packages/django/utils/autoreload.py", line 250, in raise_last_exception
    six.reraise(*_exception)
  File "/usr/local/lib/python3.5/dist-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.5/dist-packages/django/utils/autoreload.py", line 227, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/django/__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/local/lib/python3.5/dist-packages/django/apps/registry.py", line 85, in populate
    app_config = AppConfig.create(entry)
  File "/usr/local/lib/python3.5/dist-packages/django/apps/config.py", line 94, in create
    module = import_module(entry)
  File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 944, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 944, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/my_cool_directory/project/myapp/__init__.py", line 1, in <module>
    from .models import *
  File "/my_cool_directory/project/myapp/models.py", line 8, in <module>
    class Publishable(models.Model):
  File "/usr/local/lib/python3.5/dist-packages/django/db/models/base.py", line 110, in __new__
    app_config = apps.get_containing_app_config(module)
  File "/usr/local/lib/python3.5/dist-packages/django/apps/registry.py", line 247, in get_containing_app_config
    self.check_apps_ready()
  File "/usr/local/lib/python3.5/dist-packages/django/apps/registry.py", line 125, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

它不像我有严重问题,因为我可以正常方式导入应用程序。我只是好奇:为什么它不按照推荐的方式工作?

  • 并且:如何使子模块中的东西可以从topmodule导入?在apps.py?或者在__init__.py

1 个答案:

答案 0 :(得分:1)

您无法将模型导入应用的根模块。这是Django应用程序框架的局限之一。您需要从from .models import *中删除myapp/__init__.py行。

Django首先导入每个已安装应用程序的根模块。这用于设置应用程序配置,这是在不同应用程序中的模型之间设置关系字段所需的。要建立这些关系,必须加载这两个相关的应用程序。

Django了解到允许随时导入模型的艰难方法使这个过程变得非常复杂,这引入了一系列难以解决的错误。在1.7中,这个过程被大大简化,减少了错误的数量,但在这种简化中,决定在导入任何模型之前必须加载所有应用程序。