Automatic django.setup() on AppRegistryNotReady

My team does a lot of work with the Django ORM outside of request/response cycle (in particular temporal.io workflows). We are accustomed to calling django.setup() ahead of model imports and writing the noqa linter exemption about running code ahead of imports. It would be luxurious not to, and let Django try to run setup once instead of throwing AppRegistryNotReady. How crazy of an itch is that to scratch?

I tried a basic proof of concept, modifying ModelBase to include:

# Look for an application configuration to attach the model to.
try:
    app_config = apps.get_containing_app_config(module)
except django.core.exceptions.AppRegistryNotReady:
    django.setup()
    app_config = apps.get_containing_app_config(module)

That worked in a quick smoke test, didn’t break the test suite, but is obviously a hack, and simple enough that I’m sure someone’s thought of it and rejected it. At the very least there are other Django features that depend on django.setup(), so a proper change would include those. I also see a warning that apps.populate is not reentrant, though I’m not sure in practice how often that would be an issue.

Explicitly calling django.setup() in the middle of my imports is such a small annoyance I’m almost embarrassed to post here, but if removing that need responsibly is tractable in principle I’m interested in helping.

I think any solution here would be a hack, and preferable to keep out of the framework. Better to put any hacks in your project.

One option would be to (conditionally) call django.setup() in your project’s __init__.py, assuming you have a project structure like this:

example/
  - __init__.py  # here
  - app1
    - __init__.py
    - models.py

Python will resolve an import like from example.app1.models import ... by first importing example and running its __init__.py, so that would run django.setup() within your import block in all such files.