14

On Django startup I need to run some code that requires access to the database. I prefer to do this via models.

Here's what I currently have in apps.py:

from django.apps import AppConfig
from .models import KnowledgeBase

class Pqawv1Config(AppConfig):
    name = 'pqawV1'

    def ready(self):
        to_load = KnowledgeBase.objects.order_by('-timestamp').first()
        # Here should go the file loading code

However, this gives the following exception:

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

So is there a place in Django to run some startup code after the models are initialized?

3
  • 1
    Move the from .models import KnowledgeBase inside the def ready method. Here importing it in the header results in the fact that the models are loaded too early. Commented Jan 5, 2019 at 20:09
  • 1
    @WillemVanOnsem, this works, thanks. But how good is this solution? What are the side effects? I'm quite new to Python... Commented Jan 5, 2019 at 20:10
  • 1
    the difference is that you simply only import .models when the config calls ready, you thus postpone importing. It was due to "eager" importing that this resulted in trouble. Commented Jan 5, 2019 at 20:12

1 Answer 1

18

The problem is that you import .models at the top of your file. This means that, when the file app.py file is loaded, Python will load the models.py file when it evalutes that line. But that is too early. You should let Django do the loading properly.

You can move the import in the def ready(self) method, such that the models.py file is imported when ready() is called by the Django framework, like:

from django.apps import AppConfig

class Pqawv1Config(AppConfig):
    name = 'pqawV1'

    def ready(self):
        from .models import KnowledgeBase
        to_load = KnowledgeBase.objects.order_by('-timestamp').first()
        # Here should go the file loading code
Sign up to request clarification or add additional context in comments.

5 Comments

Once the data or resources is loaded in ready(), how could we use them in views? Import appconfig?
@advocado: you can obtain the appconfig for a given app with from django.apps import apps; apps.get_app_config('app_name'). If you store your resorce that is loaded on the self (so self.to_load = ...), you thus can access it with apps.get_app_config('app_name').to_load. But you should do that in a function, since the models are loaded before the ready function is triggered.
Great (and also concise) answer!
As an aside, from .models import * will fail ("SyntaxError: import * only allowed at module level") while from .models import KnowledgeBase will succeed
This is explicitly discouraged by the docs. The reason is if you run tests, the ready() code will still run against your production database, not the test database. See discussion here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.