Приложения Django еще не загружаются при использовании asgi

Я пытаюсь запустить свой проект django с использованием asgi вместо wsgi. Я настроил свои routing.py и asgi.py следующим образом:

routing.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

person kebie    schedule 08.12.2018    source источник
comment
Привет! Добавьте трассировку стека и укажите, как вы запускаете daphne.   -  person mingaleg    schedule 08.12.2018
comment
Конечно, не думал, что это нужно, готово.   -  person kebie    schedule 08.12.2018


Ответы (3)


Перед использованием инфраструктуры Django в автономном приложении вы всегда должны делать _ 1_

Итак, ваш 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()
person mingaleg    schedule 08.12.2018
comment
Спасибо, сработало. Но не могли бы вы объяснить, что именно означает автономное приложение? Поскольку я запускаю весь свой проект, я не буду называть его автономным приложением. - person kebie; 09.12.2018
comment
Перейдите по этой ссылке: docs.djangoproject.com/en/2.1/topics/settings/ - person mingaleg; 09.12.2018
comment
Что ж, ссылка гласит: «Обратите внимание, что вызов django.setup () необходим только в том случае, если ваш код действительно автономный. При запуске вашим веб-сервером или через django-admin Django сделает это за вас ». Разве в моей ситуации он не запускается веб-сервером? - person kebie; 09.12.2018

Для тех, кто использует 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)
person Arash77    schedule 23.11.2020
comment
Я последовал предложению OP и вызвал django.setup() перед каждым другим импортом. Мне также пришлось передать флаг --preload Gunicorn. - person chidimo; 01.03.2021
comment
Привет, @Arash, большое спасибо за то, что нашли время опубликовать это для версий после 3.0! Я действительно ценю это, потому что вы сэкономили мне КУЛЬТУ времени, я бы никогда не понял этого - person Tom; 27.03.2021
comment
большое спасибо, избавил меня от многих головных болей - person Samuele B.; 05.05.2021

Оказалось, что django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet ошибка в каналах lib произошла из-за недопустимый порядок импорта в моем приложении - как описано здесь .

Причина:

Я импортировал свой WSAccessTokenAuthMiddleware перед тем, как импортировать свой экземпляр django_asgi_app.

Решение:

Импорт моего django_asgi_app до WSAccessTokenAuthMiddleware устранил проблему.

# 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()),
            ])
        )
    )
})
person Lukasz Dynowski    schedule 28.05.2021