django.core.exceptions.AppRegistryNotReady: Apps a

2019-01-27 00:31发布

django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

Exception appeared when I added:

  1. import signals in init.py file (apps/application/init.py)

  2. from models import Review in signals.py file (apps/application/signals.py)

I want to send an http request when there is an insert in the model Review.

So I need to import Review model (in the __init.py__ file) to execute the following code:

@receiver (pre_save, sender = Review)
def my_handler (sender, ** kwargs):
       ....

1条回答
ゆ 、 Hurt°
2楼-- · 2019-01-27 01:18

In the Django's source, this is where the exception is comming from:

def check_apps_ready(self):
    """Raise an exception if all apps haven't been imported yet."""
    if not self.apps_ready:
        raise AppRegistryNotReady("Apps aren't loaded yet.")

As you can see it make sure every apps are ready (loaded). In general, when it is related to signals there are normally 2 situations when this happen.

  • Circular imports

    Make sure there are none in your project. This can cause the error.

  • Registering signal before the app is loaded

    See this for more information. But, one thing that help me understanding how Django works behind the scene is this statement:

It is important to understand that a Django application is just a set of code that interacts with various parts of the framework. There’s no such thing as an Application object. However, there’s a few places where Django needs to interact with installed applications, mainly for configuration and also for introspection. That’s why the application registry maintains metadata in an AppConfig instance for each installed application.

Hence, what you can do is override one of the AppConfig method called AppConfig.ready() which allow you to perform initialization tasks such as registering signals.

# yourApp/__init__.py

default_app_config = 'yourappname.apps.YourAppConfig'

# yourApp/apps.py
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    name = 'yourappname'

    def ready(self):
        from yourappname import signals

Further information

For the sake of explanation, this is the recommend way of doing since Django 1.7+ which is most likely your case. The logic behind it is that the application registry hold a boolean value ready which is set to True only after the registry is fully populated and all AppConfig.ready() methods are called.

查看更多
登录 后发表回答