Django 应用程序覆盖和导入路径?



让我们使用第三方应用程序创建一个django项目。我想在不接触原始文件的情况下覆盖它的一些模块。简单的子类化在这里是不可能的,需要透明地覆盖代码,因为许多其他应用程序依赖于原始类名和函数。

项目的结构看起来像:

django_project/
  __init__.py
  settings.py
  overrides/        <-- here is a subdir with apps overrides
    __init__.py
    payment/        <-- here is an example of app to override
      __init__.py
      admin.py
      forms.py      <-- this file is ignored, original is imported
      models.py
      tests.py
      views.py

用对settings.py进行修饰

INSTALLED_APPS=(
    'satchmo_store.shop'
    #'payment'           # original values
    'overrides.payment'  # modified app
    ...
)

然而,上述解决方案不起作用,因为Django不会将添加的应用程序的路径插入模块搜索路径(sys.path)。Django只加载admin.pymodels.pytests.pyviews.py,其他文件如forms.py将被忽略。

这种行为有记录吗?在INSTALLED_APPS中放置模块名称的幕后作用是什么

我用manage.py中的硬编码新模块搜索路径和Apache的WSGIPythonPath设置破解了这种情况。

import os.path
import sys
DIRNAME       = os.path.dirname(__file__)
APPS_OVERRIDE = os.path.join(DIRNAME, 'overrides')
if not APPS_OVERRIDE in sys.path:
    sys.path.insert(1, APPS_OVERRIDE)

我怀疑这是正确的方式。找不到描述应用程序覆盖的指南。

那么,如何在我的项目中正确地覆盖外部Django应用程序呢

额外的问题是:我需要复制整个应用程序目录树,而不仅仅是真正修改过的特定文件吗据我所知,Python会在第一个匹配的模块路径处停止,所以它不会导入搜索路径的以下部分中可用的其他模块。

如何覆盖表单的示例:

覆盖/支付/表单.py

from django import forms
class YourNewFormThingy(forms.Form): pass

覆盖/支付/型号.py

from satchmo.payment import forms as satchmo_payment_forms
from . import forms
satchmo_payment_forms.SomeForm = forms.YourNewFormThingy

尝试将paymentoverride.payment一起包含,因为satchmo使用payment模块来处理付款,而payment代码也足够灵活,可以包含您的代码。

最新更新