2013-04-29 75 views
2

我已经安装在我的Django项目两个应用程序...与类依赖性处理在Python

Contacts Package 
    Models.py 
    - class Contact 

Homes Package 
Models.py 
    - class House 

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

我的问题:房子现在依赖于联系人,这意味着我不能再安装房子的应用程序没有联系人的应用程序了。尽管这个房子应该能够没有联系人而存在。在Python中,(在框架Django的上下文中)Python人如何处理这个问题?

有没有更好的方法?

回答

3

如果House使用Contacts包仅限于单一的方法,那么你把进口的方法内捕捉到了异常:

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

或者你可以把进口在顶部该模块,但它设置为无的情况下是不可用:

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


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

如果你想去一个更纯粹的面向对象的路线,那么你可以使用Zope3适配器,但是这意味着你已经换依赖在一个包裹上依赖一组其他人。对于您所描述的问题,这可能会过度,但如果您想调查此解决方案,请参见this blog post

我认为如果你尝试这个,你会遇到的真正问题是你必须定义一个接口,例如你可以为你的House类获取的接口,如IContactProvider。该接口必须在某个地方居住,如果某处是联系人包,则最终还是需要安装该包。如果你的需求是针对某种通用的IContactProvider和几个特定的​​实现,那么这可能是处理这个问题的好方法。

+0

这是很好的OOP寿? – Prometheus 2013-04-29 09:19:22

+1

@Spike这不是一个真正的问题。关于Duncan的回答,我通常更喜欢第二种解决方案,因为我相信将所有进口都放在模块的顶部会更好。 – Bakuriu 2013-04-29 10:41:10

+0

@Spike,我添加了一个面向对象的解决方案,但是我认为对于你描述的情况来说这太过分了。 – Duncan 2013-04-29 11:18:41

1

Django作为信号和ProxyModels(当没有更好的解决方案时,Python有monkeypatching)。我通常做的事情是保持应用程序的解耦(当然,这很有意义),就是将一个“主”django应用程序用作特定于项目的集成层。在这种情况下 - 假设HouseContact(即ForeignKey)没有“硬连线”依赖性 - 我将为House定义一个ProxyModel,我将添加get_contact方法。

1

在Django中,您可以在运行时通过名称动态获取模型,这是避免循环导入的好选择。该功能是django.db.models.get_model()具有以下特征:

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

所以你在House模型代码应该看起来像

from django.db.models import get_model 
Contact = get_model('contacts', 'Contact')