3

我的 Django 项目中安装了两个应用程序...

Contacts Package
  Models.py
     - class Contact 

Homes Package
 Models.py
     - class House

House有一个名为的模型方法get_contact,在这个方法中我导入联系人和过滤器等(不重要)

我的问题: House 现在依赖于 Contacts,这意味着如果没有 Contact 应用程序,我将无法再安装 House 应用程序。尽管这所房子应该能够在没有联系人的情况下存在。在 Python 中,(在框架 Django 的上下文中)你们 Python 人如何处理这个问题?

有没有更好的办法?

4

3 回答 3

4

如果Contacts包 in的使用House仅限于单个方法,则将导入放入方法中并捕获异常:

def foo(self):
    try:
        from Contacts.Models import Contact
    except ImportError:
        return
    ... use Contact here

或者,您可以将导入放在模块的顶部,但在它不可用的情况下将其设置为 None:

try:
    from Contacts.Models import Contact
except ImportError:
    Contact = None


...
if Contact is not None:
    ... use Contact ...

如果您想走更纯粹的 OOP 路线,那么您可以使用 Zope3 适配器,但这意味着您已经将对一个包的依赖替换为对一组其他包的依赖。对于您所描述的问题,这可能是矫枉过正,但如果您想研究此解决方案,请参阅此博客文章

我认为如果您尝试这样做,您将遇到的真正问题是您必须定义一个接口,例如IContactProvider您可以为您的 House 类获取的接口。该界面必须存在于某个地方,如果那个地方是 Contacts 包,您最终仍然需要安装该包。如果您需要某种通用的IContactProvider和几个特定的​​实现,那么这可能是处理该问题的好方法。

于 2013-04-29T09:12:54.380 回答
1

In Django you can dynamically get model by name at run-time, which is good option to avoid circular imports. The function is django.db.models.get_model() with following signature:

def get_model(self, app_label, model_name, seed_cache=True, only_installed=True)

So your code in House model should look something like

from django.db.models import get_model
Contact = get_model('contacts', 'Contact')
于 2013-04-29T11:22:41.010 回答
1

Django 作为信号和 ProxyModels(当没有更好的解决方案时,Python 有猴子补丁)。我通常会做的是让应用程序解耦(当然,当它有意义时)是拥有一个“主要”django 应用程序,我将其用作特定于项目的集成层。在这种情况下——假设HouseContact(即 ForeignKey)没有“硬连线”依赖——我将定义一个 ProxyModel 来House添加get_contact方法。

于 2013-04-29T10:57:12.063 回答