我经常看到这样的结构,
MyModel.objects.all().filter(...)
字符串
这将返回默认管理器的QuerySet。起初all()
似乎是相当多余的,因为
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(...)
?如果喜欢,为什么? - 你有没有遇到过不可靠的管理者,他们会以一种不受欢迎的方式扰乱这些方法?
3条答案
按热度按时间zxlwwiss1#
管理器上的方法
all()
只是委托给get_queryset()
,正如你在Django源代码中看到的:字符串
所以这只是一种从Manager获取QuerySet的方法。这可以很方便地确保您处理的是QuerySet而不是Manager,因为
MyModel.objects
返回一个Manager。例如,如果你想覆盖所有的项目,你不能这样做:
型
因为你不能覆盖Manager。但是,
all()
返回QuerySet,你可以**覆盖QuerySet:型
通常情况下,你不应该覆盖
all()
。你可以覆盖get_queryset()
,但是这个方法必须返回一个QuerySet。如果你使用像
filter()
或exclude()
这样的过滤器方法,你已经有了QuerySet,因为这些方法被代理到QuerySet。所以你不必做像all().filter()
这样的事情。xxslljrj2#
MyModel.objects
返回管理器示例。all()
返回get_query_set()
。我认为当你需要所有对象时,一切都在那里。1.我更喜欢
MyModel.objects.filter()
,因为另一个只是一个方法调用,如果我做过滤器,我不需要所有对象:)1.这取决于目的。但是如果它们覆盖了管理器的基方法,它们将返回相同的结果格式(例如,QuerySet)
pbwdgjma3#
Mymodel.objects.filter(username='abcd')
将给予匹配记录列表Mymodel.objects.get(pk='abcd')
将返回单个记录,其主键值匹配