A signal, or equivalent, for when all apps are loaded?

550 views
Skip to first unread message

Bill Freeman

unread,
May 29, 2012, 4:42:22 PM5/29/12
to django-users
I continue to struggle with occasional circular import problems
(caused by a combination of haystack, filebrowser, and a model which
both has a search_indexes.py and a model that has a filebrowser
field).

I had thought that I had patched the issue by importing haystack in my
root urlconf (the problem doesn't happen under the development server
because it "validates models" early, but the import order was
different in production). But: 1, I kept having to add "import
haystack" to my management commands; and 2, it still occasionally
fails on restart (a timing hazard of some kind).

It strikes me that one fix would be to defer haystack's scan of the
INSTALLED_APPS until all the apps have been loaded. But when is that?
I can ask django.db.models.loading.app_cache_ready(), but it will say
False when haystack (or its models.py, which it has, despite not
having any models) is being imported (since the list of apps being
cached can't be finished until haystack.models import has finished).
So when could I run it again? It would be nice to register for an
"apps are loaded" signal, but I don't see on in the docs, and there is
no evidence of sending one in django.db.models.loading.AppCache.

Is there a right way to get something called after all the models have
been imported? (Django 1.3)

Bill

Russell Keith-Magee

unread,
May 29, 2012, 7:35:25 PM5/29/12
to django...@googlegroups.com
Unfortunately, there isn't. This is a long standing problem, and one
that the app-refactor was looking into; however, that effort hasn't
come to fruition. Django's startup sequence is an area where some work
is required. The closest thing to a "signal" you're going to get is to
hook into the URL configuration, in the same way the admin
registration process does -- but it looks like you've tried that and
haven't had any luck.

One trick that I'm aware of that *might* work in your case is to force
the validation code to run in your production stack -- for example, as
a call in your WSGI container. From a functional perspective, this is
an expensive no-op. The validation won't ever return a different
result, which is why Django's WSGI handler doesn't call validate.
However, the process of validation *does* cause the startup sequence
to be a little more predictable, because the validation mechanism
imports *all* your app modules in your project in a predictable order.
If your problem is being caused by an unpredictable import order,
forcing a specific import order may work around your problem (or at
least make the side effects more predictable, and match the behaviour
of the development server).

Yours
Russ Magee %-)

Bill Freeman

unread,
May 30, 2012, 9:59:31 AM5/30/12
to django...@googlegroups.com
Thanks Russ.

I guess that I could just try importing django.db.models in my wsgi
file (in turn imports django.db.models.loading, which initializes the
AppCache) as a validation equivalent?

Bill

Russell Keith-Magee

unread,
May 30, 2012, 7:33:11 PM5/30/12
to django...@googlegroups.com
I mentioned the validation thing because I know that it works. I'd
have to check the models import to make sure it has exactly the same
side effects, but it stands to reason that it might.

Yours,
Russ Magee %-)
Reply all
Reply to author
Forward
0 new messages