Django Channels ASGI - AppRegistryNotReady:应用程序尚未加载

问题描述 投票:0回答:5

使用

python manage.py runserver
运行我的项目可以使用通道 asgi 开发服务器完美启动它,但是当使用 Daphne (
daphne project.routing:application
) 运行项目时,我收到错误
AppRegistryNotReady: Apps aren't loaded yet

settings.py

INSTALLED_APPS = [
    'channels',
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.sites',
    # ...
    # ... installed apps and custom apps
]

WSGI_APPLICATION = 'project.wsgi.application'

ASGI_APPLICATION = 'project.routing.application'

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [REDIS_URL],
        }
    },
}

routing.py

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

from django.core.asgi import get_asgi_application
from django.conf.urls import url

from my_app.consumers import MyCustomConsumer

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    'websocket': AuthMiddlewareStack(
        URLRouter([
            url(r'^ws/custom/$', MyCustomConsumer),
        ])
    ),
})

我尝试按照其他问题中的描述添加

django.setup()
,以及使用
uvicorn
而不是
daphne
运行,但仍然遇到相同的错误。我还尝试指向
settings.CHANNEL_LAYERS['ROUTING']
中的 websocket 路由并将应用程序初始化移至
asgi.py
文件,但也没有运气。我不知道我在做什么与渠道文档不同,任何帮助表示赞赏。

django django-channels daphne uvicorn asgi
5个回答
11
投票

尽早获取 Django ASGI 应用程序以确保填充 AppRegistry 在导入消费者和可能导入 ORM 的 AuthMiddlewareStack 之前 型号。

import os
from django.conf.urls import url
from django.core.asgi import get_asgi_application

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

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

from my_app.consumers import MyConsumer

application = ProtocolTypeRouter({
# Django's ASGI application to handle traditional HTTP requests
"http": django_asgi_app,
# WebSocket chat handler
"websocket": AuthMiddlewareStack(
    URLRouter([
        path('ws/custom/', MyConsumer),
    ])
),

})


2
投票

asgi.py

import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chat.settings')
django.setup()

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from chat import routing

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
       )
    )
})

1
投票

上面提到的对我来说没有任何作用。但我尝试使用以下配置在本地计算机上工作:

import os
from django.core.asgi import get_asgi_application

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

from channels.routing import ProtocolTypeRouter, URLRouter
from app.tokenAuthMiddleware import TokenAuthMiddleware
from app.routing import channel_routing

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": TokenAuthMiddleware(
     URLRouter(channel_routing)
    )
})

然后运行以下命令:

gunicorn app.asgi:application -k uvicorn.workers.UvicornH11Worker

使用

UvicornH11Worker
而不是
UvicornWorker
对我有用。

您可以查看以下链接作为参考: uvicorn 与 Gunicorn 一起奔跑


0
投票

问题源自将 daphne 服务器指向

routing.py
中的应用程序,而它需要指向
asgi.py
文件。但是,在
settings.py
内,
ASGI_APPLICATION
需要指向
routing.py
文件中的应用程序。

asgi.py

import os
import django
from channels.routing import get_default_application

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

设置.py

ASGI_APPLICATION = 'project.routing.application'

路由.py

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.urls import path

from my_app.consumers import MyConsumer


application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter([
            path('ws/custom/', MyConsumer),
        ])
    ),
})

然后使用

daphne project.asgi:application

运行 daphne 服务器

0
投票

对于使用 Django > 3.0 的任何人,请参阅下面的链接:

https://github.com/django/channels/issues/1564#issuecomment-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)
© www.soinside.com 2019 - 2024. All rights reserved.