Django ORM - objects.filter()与objects.all().filter()-哪一个更好?

7ajki6be  于 2023-11-20  发布在  Go
关注(0)|答案(3)|浏览(143)

我经常看到这样的结构,

  1. MyModel.objects.all().filter(...)

字符串
这将返回默认管理器的QuerySet。起初all()似乎是相当多余的,因为

  1. MyMode.objects.filter(...)


都能得到同样的结果
然而,这似乎只对默认管理器是安全的,因为Django文档中有以下两条声明:
摘自“添加额外的管理器方法”一章
一个自定义的Manager方法可以返回任何你想要的东西。它不需要返回一个QuerySet。
all()管理器方法的定义:
all()返回当前QuerySet(或QuerySet子类)的副本。这在您可能希望传入模型管理器或QuerySet并对结果进行进一步筛选的情况下可能很有用。在任一对象上调用all()后,您肯定会有一个QuerySet可供使用。
这对我来说似乎有点矛盾。一方面Django提供了让管理器方法返回任何首选对象类型的自由,另一方面它需要all()方法的QuerySet。我知道每个管理器都有一个get_queryset方法,由all()调用。但是谁阻止我在自定义管理器中覆盖all()呢?虽然我同意这样做是不好的设计。

  • 所以就我所知,all()方法并不能保证返回一个QuerySet。MyModel.objects到底返回什么?这条语句调用了all()?还是`get_queryset()?
  • 你喜欢MyModel.objects.filter(...)还是MyModel.objects.all().filter(...)?如果喜欢,为什么?
  • 你有没有遇到过不可靠的管理者,他们会以一种不受欢迎的方式扰乱这些方法?
zxlwwiss

zxlwwiss1#

管理器上的方法all()只是委托给get_queryset(),正如你在Django源代码中看到的:

  1. def all(self):
  2. return self.get_queryset()

字符串
所以这只是一种从Manager获取QuerySet的方法。这可以很方便地确保您处理的是QuerySet而不是Manager,因为MyModel.objects返回一个Manager。
例如,如果你想覆盖所有的项目,你不能这样做:

  1. for item in MyModel.objects:
  2. # this won't work


因为你不能覆盖Manager。但是,all()返回QuerySet,你可以**覆盖QuerySet:

  1. for item in MyModel.objects.all():
  2. # do someting with item


通常情况下,你不应该覆盖all()。你可以覆盖get_queryset(),但是这个方法必须返回一个QuerySet。
如果你使用像filter()exclude()这样的过滤器方法,你已经有了QuerySet,因为这些方法被代理到QuerySet。所以你不必做像all().filter()这样的事情。

展开查看全部
xxslljrj

xxslljrj2#

  1. MyModel.objects返回管理器示例。all()返回get_query_set()。我认为当你需要所有对象时,一切都在那里。
    1.我更喜欢MyModel.objects.filter(),因为另一个只是一个方法调用,如果我做过滤器,我不需要所有对象:)
    1.这取决于目的。但是如果它们覆盖了管理器的基方法,它们将返回相同的结果格式(例如,QuerySet)
pbwdgjma

pbwdgjma3#

Mymodel.objects.filter(username='abcd')将给予匹配记录列表Mymodel.objects.get(pk='abcd')将返回单个记录,其主键值匹配

相关问题