Ответ 1
В Django 1.7 приложения могут реализовать метод ready(): https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready
Мне нужно выполнить некоторые довольно простые задачи после того, как моя среда Django была "полностью загружена".
В частности, мне нужно делать такие вещи, как Signal.disconnect()
некоторые Django-сигналы, которые по умолчанию устанавливаются моей третьей стороной, и connect
мои собственные сигналы, и мне нужно сделать "патч обезьян" , чтобы добавить функции удобства к некоторым моделям Django из другой библиотеки.
Я делал это в файле Django app __init__.py
, который, похоже, отлично работает для исправления обезьян, но не работает для моего отключения сигнала. Проблема, по-видимому, одна из сроков - по какой-то причине Третья партийная библиотека всегда, кажется, называет ее Signal.connect()
после того, как я попытаюсь ее Signal.disconnect()
.
Итак, два вопроса:
Есть ли у меня гарантия, основанная на порядке моего INSTALLED_APPS
порядка загрузки моего приложения __init__.py
?
Есть ли место для размещения логики, которая должна запускаться после Приложения Django полностью загружены в память?
В Django 1.7 приложения могут реализовать метод ready(): https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready
Мой вопрос - более плохо сформулированный дубликат этого вопроса: Куда поместить код запуска Django. Ответ исходит из этого вопроса:
Запишите промежуточное программное обеспечение, которое делает это в init, а затем повысит django.core.exceptions.MiddlewareNotUsed из init, django удалит его для всех запросов...
См. документацию Django при написании собственного промежуточного программного обеспечения.
Мне нужно было сделать следующее исправление обезьяны. Я использую 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)
Насколько я знаю, нет такой вещи, как "полная загрузка". Множество функций Django включает import something
прямо в функцию. Импорт произойдет только в том случае, если вы действительно используете эту функцию. Единственный способ сделать то, что вы хотите, - это явно импортировать вещи, которые вы хотите исправить (которые вы можете сделать в любом месте), а затем исправить их. После этого любой другой импорт будет повторно использовать их.