【问题标题】:Django Channels ASGI - AppRegistryNotReady: Apps aren't loaded yetDjango Channels ASGI - AppRegistryNotReady:应用程序尚未加载
【发布时间】:2021-02-09 00:18:23
【问题描述】:

使用 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


【解决方案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 running with gunicorn

【讨论】:

    【解决方案2】:

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

    })

    【讨论】:

    • 尝试后出现如下错误:TypeError asgiref.compatibility in new_application __call__() missing 1 required positional argument: 'send'
    【解决方案3】:

    问题源于将 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'
    

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

    【讨论】:

      猜你喜欢
      • 2019-05-10
      • 2016-05-07
      • 2020-08-11
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多