Django"完全加载"后如何运行任意代码

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应用程序完全加载到内存,是否有适当的位置来放置需要运行的逻辑?

gue*_*tli 8

在Django 1.7中,Apps可以实现ready()方法:https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready

  • 仅当您能够修改“settings.INSTALLED_APPS”时,此功能才有效。很多导致这个问题的用例都没有那么奢侈。 (2认同)

Chr*_* W. 7

我的问题是这个问题的措辞更加糟糕:Django Startup Code放在哪里.答案来自这个问题:

编写在init中执行此操作的中间件,然后从init中提升django.core.exceptions.MiddlewareNotUsed ,django将为所有请求删除它...

有关编写自己的中间件的信息,请参阅Django 文档.

  • 我发现这在第一次请求时做的一切都很可怕......它应该在启动时完成. (3认同)

小智 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)