Monkey在另一个应用程序中修补Django应用程序



我们在Django 1.9应用程序中使用了第三方库。我们想用原始应用程序中没有的一些功能来修改该应用程序(针对MongoDB)。我们目前通过我们自己的原始lib分支来实现这一点,但希望使更改更加正交,这样它们最终可能会被拉向上游。

我们已经尝试在应用程序config ready()中进行修补,但模型导入在django.apps.registry.populate()中的此调用之前进行处理,在__init__中执行此操作会受到apps_ready == False的影响。在生命周期中执行此操作的最佳部分是什么?

class MongoConfig(AppConfig):
    def __init__(self, app_name, app_module):
        super(MongoConfig, self).__init__(app_name, app_module)
        for p in patches:
            patch(*p)
def patch(old, new):
    old_module, old_item = split_mod(old)
    new_module, new_item = split_mod(new)
    print('patching {0} with {1}'.format(old, new))
    old_module = import_module(old_module)
    new_module = import_module(new_module)
    setattr(old_module, old_item, getattr(new_module, new_item))

我真的不喜欢monkey补丁(除了在测试用例中,即使在那时我也相信mock更好)。

你为什么不试试更简单的选择?在你的项目中创建一个应用程序的代理(由于Python的查找系统,它将首先被调用),然后简单地修补你想要的方法,并绕过你不想要的方法到原始应用程序。

因此,如果该组件名为"FooProject",您将在您的项目中创建另一个名为"FooProject"的应用程序,在该应用程序的__init__.py:中

from originalproject import FooProject as OriginalFoo
class FooProject(OriginalFoo):
    def override_method_here(self, foo):
       return my_own_magic(foo)

我最终在初始化的wsgi部分完成了这项工作

在wsgi.py中

# Monkey Patch a few things
from huey_monitor.apps import HueyMonitorConfig
HueyMonitorConfig.verbose_name = 'Task Monitor'

Monkey补丁是一种破解,很难维护,应该避免。

原则是在导入代码之前,在加载Django本身之前对代码进行修补。根据你的切入点,你会找到合适的地方来修补你的代码。

使用Django 1.9,我可以考虑两个入口点:

  1. wsgi.py-当您的代码在wsgi容器上运行时
  2. manage.py-运行任何管理命令(shell、runserver、migrate)时

我只是有一个类似的需求,需要对django-allauth/django-invitation适配器进行猴子补丁,但偶然发现了同样的限制(apps_ready == False)。

因此,我部分使用了@domtes提到的内容,编辑manage.py并在其中插入一个方法来部分重写我必须修改的适配器,从而附加所需的行为。当django加载django-invitations时,该方法已经被重写。

这是一个简单,肮脏,可能不建议搜索&replace方法,其中我重写了属于库结构的目标CCD_ 11文件。

它应该与未来的版本兼容,但我承认这是错误和问题的根源。

干杯

相关内容

  • 没有找到相关文章

最新更新