Chr*_* W. 18 python django monkeypatching django-signals
在我的Django环境"完全加载"之后,我需要执行一些相当简单的任务.
更具体地说,我需要做一些像Signal.disconnect()我的第三方库默认设置的Django Signals和connect我自己的Signals,我需要做一些"猴子修补",以便从另一个库中为一些Django模型添加便利功能.
我一直在我的Django应用程序的__init__.py文件中做这些东西,这似乎适用于猴子修补,但不适用于我的信号断开连接.问题似乎是时间问题 - 无论出于什么原因,第三方图书馆Signal.connect()在我尝试之后似乎总是称之为Signal.disconnect()它.
所以有两个问题:
根据INSTALLED_APPS我的应用程序__init__.py模块加载时的顺序,我有任何保证吗?
在 Django应用程序完全加载到内存后,是否有适当的位置来放置需要运行的逻辑?
在Django 1.7中,Apps可以实现ready()方法:https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready
我的问题是这个问题的措辞更加糟糕:Django Startup Code放在哪里.答案来自这个问题:
编写在init中执行此操作的中间件,然后从init中提升django.core.exceptions.MiddlewareNotUsed ,django将为所有请求删除它...
有关编写自己的中间件的信息,请参阅Django 文档.
小智 5
我必须做以下猴子修补。我从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
Run Code Online (Sandbox Code Playgroud)
然后您可以像其他任何信号一样使用此信号:
def django_apps_loaded_receiver(sender, *args, **kwargs):
# put your code here.
django_apps_loaded.connect(django_apps_loaded_receiver)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7318 次 |
| 最近记录: |