【问题标题】:Django apps aren't loaded yet when using asgi使用 asgi 时尚未加载 Django 应用程序
【发布时间】:2019-05-10 01:30:18
【问题描述】:

我正在尝试使用 asgi 而不是 wsgi 来运行我的 django 项目。我的 routing.py 和 asgi.py 设置如下:

路由.py

from django.conf.urls import url
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator, 
OriginValidator
from channels.auth import AuthMiddlewareStack

from some.consumers import SomeConsumer


application = ProtocolTypeRouter({
    'websocket': AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                [
                    url(r'^some_url/$', SomeConsumer),
                ]
            )
         )
    )
})

asgi.py

import os
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
application = get_default_application()

现在,您可以看到它是标准设置,并且可以在默认 django 服务器上正常运行,但是当我尝试使用其他一些(daphne 或 uvicorn)运行时,它会引发此异常。

这是我的INSTALLED_APPS

INSTALLED_APPS = [
    'channels',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'django_jenkins',
    'easy_thumbnails',
    'image_cropping',
    'allauth',
    'allauth.account',
    'and_rest_of_my_own_apps',
]

有人遇到过这样的问题吗?

---- 编辑----

这是一个堆栈跟踪:

Traceback (most recent call last):

File "/path/to/my/env/bin/daphne", line 11, in <module>
    sys.exit(CommandLineInterface.entrypoint())
  File "/path/to/my/env/lib/python3.6/site-packages/daphne/cli.py", line 161, in entrypoint
    cls().run(sys.argv[1:])
  File "/path/to/my/env/lib/python3.6/site-packages/daphne/cli.py", line 222, in run
    application = import_by_path(args.application)
  File "/path/to/my/env/lib/python3.6/site-packages/daphne/utils.py", line 12, in import_by_path
    target = importlib.import_module(module_path)
  File "/path/to/my/env/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "./my_project/asgi.py", line 5, in <module>
    application = get_default_application()
  File "/path/to/my/env/lib/python3.6/site-packages/channels/routing.py", line 33, in get_default_application
    module = importlib.import_module(path)
  File "/path/to/my/env/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "./my_project/routing.py", line 4, in <module>
    from channels.auth import AuthMiddlewareStack
  File "/path/to/my/env/lib/python3.6/site-packages/channels/auth.py", line 12, in <module>
    from django.contrib.auth.models import AnonymousUser
  File "/path/to/my/env/lib/python3.6/site-packages/django/contrib/auth/models.py", line 2, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "/path/to/my/env/lib/python3.6/site-packages/django/contrib/auth/base_user.py", line 47, in <module>
    class AbstractBaseUser(models.Model):
  File "/path/to/my/env/lib/python3.6/site-packages/django/db/models/base.py", line 100, in __new__
    app_config = apps.get_containing_app_config(module)
  File "/path/to/my/env/lib/python3.6/site-packages/django/apps/registry.py", line 244, in get_containing_app_config
    self.check_apps_ready()
  File "/path/to/my/env/lib/python3.6/site-packages/django/apps/registry.py", line 127, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

和命令

daphne -b 0.0.0.0 -p 8000 my_project.asgi:application --access-log=./logs/daphne-access.log

【问题讨论】:

  • 嗨!请添加堆栈跟踪并指定如何启动daphne。
  • 当然,认为不需要,完成。

标签: django django-channels asgi


【解决方案1】:

在独立应用程序中使用 Django 基础架构之前,您应该始终执行django.setup()

所以,你的asgi.py 应该是这样的

import os
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
django.setup()
application = get_default_application()

【讨论】:

  • 谢谢,它成功了。但是你能解释一下独立应用程序的确切含义吗?因为我运行整个项目,所以我不会将其称为独立应用程序。
  • 嗯,链接说“请注意,只有在您的代码真正独立时才需要调用 django.setup()。当您的 Web 服务器或通过 django-admin 调用时,Django 将为您处理此问题。在我的情况下它不是由网络服务器调用的吗?
【解决方案2】:

对于使用 Django > 3.0 的任何人,请参阅下面的链接。它对我有用

https://www.gitmemory.com/issue/django/channels/1564/722354397

您所要做的就是在导入任何其他内容之前致电get_asgi_application()

我的asgi.py 文件示例:

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django_asgi_app = get_asgi_application()

from django.conf import settings
from .routing import asgi_routes

asgi_routes["http"] = django_asgi_app
application = ProtocolTypeRouter(asgi_routes)

【讨论】:

  • 我听从了那里的 OP 的建议,并在所有其他导入之前调用了 django.setup()。我还必须将 --preload 标志传递给 gunicorn。
  • 嗨@Arash 非常感谢您抽出时间为 3.0 之后的版本发布此内容!真的很感激,因为你为我节省了大量时间,我永远不会想到这一点
  • 非常感谢,帮我省了很多麻烦
【解决方案3】:

原来Channels lib 中的django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet 错误是由于我的应用程序中的无效的导入顺序而发生的 - 正如here 所解释的那样。

原因:

我在导入 django_asgi_app 实例之前导入了 WSAccessTokenAuthMiddleware。

解决方案:

在WSAccessTokenAuthMiddleware 之前导入我的django_asgi_app 解决了问题。

# First, import app created by get_asgi_application() - django.core.asgi
from general.settings.asgi import application as django_asgi_app

# Second, import my middleware and consumers
from general.consumers import ModelConsumer
from general.util.auth import WSAccessTokenAuthMiddleware

# Third, Import channels classes
from django.conf.urls import url
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter
from channels.routing import URLRouter


application = ProtocolTypeRouter({
    "http": django_asgi_app,
    'websocket': WSAccessTokenAuthMiddleware(
        AuthMiddlewareStack(
            URLRouter([
                url('ws/models/(?P<model_name>\w+)', ModelConsumer.as_asgi()),
            ])
        )
    )
})

【讨论】:

    猜你喜欢
    • 2021-02-09
    • 2017-08-21
    • 2018-11-29
    • 2016-08-04
    • 2016-06-01
    • 2016-01-08
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多