13

使用类似的东西有什么缺点吗

from django.db.models.loading import get_model

def get_something():
    model = get_model('app', 'Model')
    return model.something()

代替

from app.models import Model

def get_something():
    return Model.something()

第二个例子会导致循环依赖,而第一个例子不会,但第二个例子更常见。

更新:如果第二个示例在名为 Other_Model 的模型中,并且模型也导入了 Other_Model —— 一个简单的循环导入,你会得到循环依赖错误。

4

2 回答 2

12

通常,该get_model功能是为需要动态加载模型的时候保留的(例如,如果您不知道是否有人会通过 myapp.Person、myapp.Place 或 myapp.Thing 服务并且他们都有相同的界面)。我什至会说,任何其他用途都应该在代码审查中自动标记,如果没有其他原因,除了它引入了意想不到的事实。

至于内部机制,确实没有实质性差异。版本不可避免地get_model会调用__import__. 也就是说,它并非没有错误。使用实际import语句将避免这个问题。


在MRO问题上,循环导入无法通过重构解决的情况很少见。如果您有两个相互依赖的应用程序导致循环导入,那么您真的需要重新考虑这些应用程序。(我的猜测是你真的在处理一个应用程序。)

于 2013-05-29T01:50:04.407 回答
5

get_model如果您的应用程序路径不那么直截了当,使用可能会令人困惑。

例如,如果您的模型存在于 中apps.MyApp.models.misc.MyModel,那么调用会get_model('MyApp', 'misc.MyModel')不太直观。您可能必须通过反复试验或挖掘源代码来解决这个问题。

(请注意,这适用于 Django 1.6 及之前版本。Django 1.7+ 对应用程序命名进行了很多更改,这可能已经更改)


另一种避免循环依赖的方法是直接在方法中进行导入,如下所示:

def get_something():
    from app.models import Model
    return Model.something()

这会将导入推迟到第一次调用该方法。

于 2014-09-23T17:07:41.960 回答