Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
761 views
in Technique[技术] by (71.8m points)

python - django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. file init

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):
       ....
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...