在模型类中使用Django管理器与静态方法的对比

41 投票
1 回答
13620 浏览
提问于 2025-04-17 03:54

在了解了Django的管理器(Managers)之后,我还是不太确定使用它能带来多少好处。看起来最好的用法是添加一些自定义查询(只读)方法,比如 XYZ.objects.findBy*()。不过,我其实可以很简单地通过模型类的静态方法来实现这些功能。

我总是更喜欢后者,因为:

  1. 代码更集中,读起来更清晰,维护起来也更简单。
  2. 稍微简洁一点,因为我在调用时不需要加上 objects 属性。
  3. Manager 类在模型继承方面有一些奇怪的规则,干脆不碰它们比较好。

有没有什么好的理由让人选择不使用静态方法,而是使用管理器类呢?

1 个回答

48

在Django中,给管理器添加自定义查询是一个常见的做法。根据Django文档关于自定义管理器的说明:

添加额外的管理器方法是给模型增加“表级”功能的推荐方式。

如果你是在做自己的私有应用,这个推荐的做法就没那么重要了——实际上,我公司内部的代码库里就有几个类方法,可能更适合放在自定义管理器里。

不过,如果你写的是要和其他Django用户分享的应用,他们会期待在自定义管理器中看到findBy这个方法。

我觉得你提到的继承问题并没有那么严重。如果你看看自定义管理器和模型继承的文档,你应该不会遇到麻烦。写.objects虽然有点啰嗦,但就像我们用XYZ.objects.get()XYZ.objects.all()查询时一样,还是能接受的。

在我看来,使用管理器方法有几个好处:

  1. API的一致性。你的方法findBygetfilteraggregate等方法在一起。想知道在XYZ.objects管理器上可以做哪些查找?用dir(XYZ.objects)查看就简单了。

  2. 静态方法会让实例的命名空间变得杂乱。XYZ.findBy()没问题,但如果你定义了一个静态方法,你也可以用xyz.findBy()。在特定实例上运行findBy查找其实没什么意义。

  3. 避免重复代码。有时候你可以在多个模型上使用同一个管理器。

说了这么多,最终还是看你自己。我没有发现不使用静态方法的绝对理由。你是成年人,这是你的代码,如果你不想把findBy写成管理器方法,世界也不会因此崩塌;)

如果想进一步了解,我推荐阅读James Bennett写的博客文章管理器与类方法,他是Django的发布经理。

撰写回答