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'] и перенести инициализацию приложения в файл asgi.py, но и там не повезло. Я не могу сказать, что я делаю иначе, чем в документации каналов, любая помощь приветствуется.


person Shonin    schedule 26.10.2020    source источник


Ответы (3)


Получите приложение Django ASGI заблаговременно, чтобы обеспечить заполнение AppRegistry перед импортом потребителей и AuthMiddlewareStack, которые могут импортировать модели ORM.

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),
    ])
),

})

person Yooy Altroo    schedule 25.11.2020

Проблема возникла из-за того, что сервер 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 с daphne project.asgi:application

person Shonin    schedule 26.10.2020

Ничего не работало для меня, упомянутого выше. Но я попытался с приведенной ниже конфигурацией для работы на локальной машине:

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

person goutham_mi3    schedule 27.05.2021