Как запустить произвольный код после того, как Django "полностью загружен"

Мне нужно выполнить некоторые довольно простые задачи после того, как моя среда Django была "полностью загружена".

В частности, мне нужно делать такие вещи, как Signal.disconnect() некоторые Django-сигналы, которые по умолчанию устанавливаются моей третьей стороной, и connect мои собственные сигналы, и мне нужно сделать "патч обезьян" , чтобы добавить функции удобства к некоторым моделям Django из другой библиотеки.

Я делал это в файле Django app __init__.py, который, похоже, отлично работает для исправления обезьян, но не работает для моего отключения сигнала. Проблема, по-видимому, одна из сроков - по какой-то причине Третья партийная библиотека всегда, кажется, называет ее Signal.connect() после того, как я попытаюсь ее Signal.disconnect().

Итак, два вопроса:

Есть ли у меня гарантия, основанная на порядке моего INSTALLED_APPS порядка загрузки моего приложения __init__.py?

Есть ли место для размещения логики, которая должна запускаться после Приложения Django полностью загружены в память?

Ответы

Ответ 2

Мой вопрос - более плохо сформулированный дубликат этого вопроса: Куда поместить код запуска Django. Ответ исходит из этого вопроса:

Запишите промежуточное программное обеспечение, которое делает это в init, а затем повысит django.core.exceptions.MiddlewareNotUsed из init, django удалит его для всех запросов...

См. документацию Django при написании собственного промежуточного программного обеспечения.

Ответ 3

Мне нужно было сделать следующее исправление обезьяны. Я использую django 1.5 из ветки github. Я не знаю, подходит ли это для этого, но он работает для меня.

Я не мог использовать промежуточное ПО, потому что я также хотел, чтобы скрипты manage.py были затронуты.

в любом случае, вот этот довольно простой патч:

import django
from django.db.models.loading import AppCache

django_apps_loaded = django.dispatch.Signal()

def populate_with_signal(cls):
    ret = cls._populate_orig()
    if cls.app_cache_ready():
        if not hasattr(cls, '__signal_sent'):
            cls.__signal_sent = True
            django_apps_loaded.send(sender=None)
    return ret

if not hasattr(AppCache, '_populate_orig'):
    AppCache._populate_orig = AppCache._populate
    AppCache._populate = populate_with_signal

а затем вы можете использовать этот сигнал, как и любой другой:

def django_apps_loaded_receiver(sender, *args, **kwargs):
    # put your code here.
django_apps_loaded.connect(django_apps_loaded_receiver)

Ответ 4

Насколько я знаю, нет такой вещи, как "полная загрузка". Множество функций Django включает import something прямо в функцию. Импорт произойдет только в том случае, если вы действительно используете эту функцию. Единственный способ сделать то, что вы хотите, - это явно импортировать вещи, которые вы хотите исправить (которые вы можете сделать в любом месте), а затем исправить их. После этого любой другой импорт будет повторно использовать их.