在我的Django环境“完全加载”之后,我需要执行一些相当简单的任务。
更具体地说,我需要执行Signal.disconnect()
某些Django信号,这些信号默认由我的第三方库设置,connect
我自己的信号,我需要做一些"monkey patching"到从其他库中为一些Django模型添加便利函数。
我一直在我的Django应用程序的__init__.py
文件中执行此操作,这似乎适用于猴子修补,但不适用于我的信号断开连接。问题似乎是时间问题 - 无论出于何种原因,第三方图书馆在我尝试Signal.connect()
之后似乎总是将其称为Signal.disconnect()
。
所以有两个问题:
根据INSTALLED_APPS
我的应用__init__.py
模块加载时的顺序,我是否有任何保证?
在 Django应用程序已完全加载到内存后,是否有适当的位置放置需要运行 的逻辑?
答案 0 :(得分:7)
在Django 1.7中,Apps可以实现ready()方法:https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready
答案 1 :(得分:5)
我的问题是这个问题的措辞较差:Where To Put Django Startup Code。答案来自这个问题:
编写在 init 中执行此操作的中间件,然后从 init 中提升django.core.exceptions.MiddlewareNotUsed,django将删除所有请求...
答案 2 :(得分:4)
我必须做以下猴子补丁。我从github分支使用django 1.5。我不知道这是否是正确的方法,但它对我有用。
我无法使用中间件,因为我还希望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)
答案 3 :(得分:3)
据我所知,没有“满载”这样的东西。在函数中有很多Django函数包括import something
。只有在实际调用该函数时才会发生这些导入。做你想做的事的唯一方法是明确地导入你想要修补的东西(你应该可以在任何地方做),然后修补它们。此后,任何其他进口将重复使用它们。