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

问题描述

使用python manage.py runserver运行我的项目时,可以使用通道asgi开发服务器将其完美启动,但是使用达芙妮(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文件中,但也没有运气。我无法从渠道文档中看出自己在做什么,感谢任何帮助。

解决方法

问题是将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()

settings.py

ASGI_APPLICATION = 'project.routing.application'

routing.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服务器

,

尽早获取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/',])
),

})

,

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

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 running with gunicorn