在模型类中使用Django管理器与静态方法的对比
在了解了Django的管理器(Managers)之后,我还是不太确定使用它能带来多少好处。看起来最好的用法是添加一些自定义查询(只读)方法,比如 XYZ.objects.findBy*()
。不过,我其实可以很简单地通过模型类的静态方法来实现这些功能。
我总是更喜欢后者,因为:
- 代码更集中,读起来更清晰,维护起来也更简单。
- 稍微简洁一点,因为我在调用时不需要加上
objects
属性。 Manager
类在模型继承方面有一些奇怪的规则,干脆不碰它们比较好。
有没有什么好的理由让人选择不使用静态方法,而是使用管理器类呢?
1 个回答
在Django中,给管理器添加自定义查询是一个常见的做法。根据Django文档关于自定义管理器的说明:
添加额外的管理器方法是给模型增加“表级”功能的推荐方式。
如果你是在做自己的私有应用,这个推荐的做法就没那么重要了——实际上,我公司内部的代码库里就有几个类方法,可能更适合放在自定义管理器里。
不过,如果你写的是要和其他Django用户分享的应用,他们会期待在自定义管理器中看到findBy
这个方法。
我觉得你提到的继承问题并没有那么严重。如果你看看自定义管理器和模型继承的文档,你应该不会遇到麻烦。写.objects
虽然有点啰嗦,但就像我们用XYZ.objects.get()
和XYZ.objects.all()
查询时一样,还是能接受的。
在我看来,使用管理器方法有几个好处:
API的一致性。你的方法
findBy
和get
、filter
、aggregate
等方法在一起。想知道在XYZ.objects
管理器上可以做哪些查找?用dir(XYZ.objects)
查看就简单了。静态方法会让实例的命名空间变得杂乱。
XYZ.findBy()
没问题,但如果你定义了一个静态方法,你也可以用xyz.findBy()
。在特定实例上运行findBy
查找其实没什么意义。避免重复代码。有时候你可以在多个模型上使用同一个管理器。
说了这么多,最终还是看你自己。我没有发现不使用静态方法的绝对理由。你是成年人,这是你的代码,如果你不想把findBy
写成管理器方法,世界也不会因此崩塌;)
如果想进一步了解,我推荐阅读James Bennett写的博客文章管理器与类方法,他是Django的发布经理。