Python Django ORM - objects.filter() 与 objects.all().filter() - 哪个更受欢迎?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22804252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django ORM - objects.filter() vs. objects.all().filter() - which one is preferred?
提问by Dr.Elch
Very often I see constructs like
我经常看到这样的结构
MyModel.objects.all().filter(...)
which will return a QuerySet of the default Mananger. At first all()
seems to be quite redundant, because
这将返回默认 Mananger 的 QuerySet。乍一看all()
似乎很多余,因为
MyMode.objects.filter(...)
delivers the same result.
提供相同的结果。
However, this seems to be safe for the default Manager only, because of the following two statements in the Django documentation:
但是,这似乎仅对默认管理器是安全的,因为 Django 文档中有以下两个语句:
Excerpt from the Chapter "Adding extra manager methods"
摘自“添加额外的管理器方法”一章
A custom Manager method can return anything you want. It doesn't have to return a QuerySet.
自定义 Manager 方法可以返回您想要的任何内容。它不必返回 QuerySet。
Definition of the all()
manager method:
all()
manager方法的定义:
all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result. After calling all() on either object, you'll definitely have a QuerySet to work with.
all() 返回当前 QuerySet(或 QuerySet 子类)的副本。这在您可能希望传入模型管理器或 QuerySet 并对结果进行进一步过滤的情况下非常有用。在任一对象上调用 all() 之后,您肯定会有一个 QuerySet 可以使用。
This seems a bit like a contradiction to me. On one hand Django offers the freedom to let a manager method return whatever object type is preferred and on the other hand it requires a QuerySet for the all()
method. I'm aware that each manager has a get_queryset
method which is called by all()
. But who stops me from overriding all()
in my custom manager? Although I agree it would be bad design to do so.
这对我来说似乎有点矛盾。一方面,Django 提供了让管理器方法返回任何首选对象类型的自由,另一方面,它需要该all()
方法的 QuerySet 。我知道每个经理都有一个get_queryset
由all()
. 但是谁阻止我覆盖all()
自定义管理器?虽然我同意这样做是糟糕的设计。
So as far as I can see, the
all()
method does not guarantee to return a QuerySet. What exactly doesMyModel.objects
return? Does this statement callall()
? or `get_queryset()?Do you prefer
MyModel.objects.filter(...)
orMyModel.objects.all().filter(...)
. And if so, why?Have you ever encountered wonky managers that would mess with those methods in a undesirable way?
所以据我所知,该
all()
方法不保证返回一个 QuerySet。究竟MyModel.objects
返回什么?这个说法叫all()
吗?或`get_queryset()?你喜欢
MyModel.objects.filter(...)
还是MyModel.objects.all().filter(...)
. 如果是这样,为什么?您是否遇到过会以不受欢迎的方式使用这些方法的不稳定经理?
采纳答案by gitaarik
The method all()
on a manager just delegates to get_queryset()
, as you can see in the Django source code:
all()
管理器上的方法只是委托给get_queryset()
,正如您在Django 源代码中看到的:
def all(self):
return self.get_queryset()
So it's just a way to get the QuerySet from the Manager. This can be handy to ensure that you're dealing with a QuerySetand not a Manager, because MyModel.objects
returns a Manager.
所以这只是一种从 Manager 获取 QuerySet 的方法。这可以方便地确保您处理的是QuerySet而不是Manager,因为MyModel.objects
返回一个 Manager。
For example, if you want to iterate over all the items, you can'tdo this:
例如,如果要遍历所有项目,则不能这样做:
for item in MyModel.objects:
# do something with item
Because you can't iterate over a Manager. However, all()
returns the QuerySet, you caniterate over a QuerySet:
因为你不能迭代一个 Manager。但是,all()
返回 QuerySet,您可以遍历 QuerySet:
for item in MyModel.objects.all():
# do something with item
Generally, you should never overwrite all()
. You can overwrite get_queryset()
but this method mustreturn a QuerySet.
通常,您永远不应该覆盖all()
. 您可以覆盖,get_queryset()
但此方法必须返回一个 QuerySet。
If you would use a filter method like filter()
or exclude()
, you would already have the QuerySet, because these methods are proxied to the QuerySet. So you don't have to do something like all().filter()
.
如果您将使用类似filter()
或的过滤器方法exclude()
,则您已经拥有 QuerySet,因为这些方法被代理到 QuerySet。所以你不必做类似的事情all().filter()
。
回答by Bogdan Iulian Bursuc
MyModel.objects
returns the manager instance.all()
returnget_query_set()
. I think all is there for when you need all objects.- I prefer
MyModel.objects.filter()
cause the other is just one more method call, and I don't need all objects if I do filter :) - It depends on the purpose. But if they override a base method of the manager, they return the same result format (eg. a QuerySet)
MyModel.objects
返回管理器实例。all()
返回get_query_set()
。我认为当您需要所有对象时,一切都在那里。- 我更喜欢
MyModel.objects.filter()
因为另一个只是一个方法调用,如果我进行过滤,我不需要所有对象:) - 这取决于目的。但是如果它们覆盖了管理器的基本方法,它们将返回相同的结果格式(例如一个 QuerySet)
回答by aarif faridi
Mymodel.objects.filter(username='abcd')
will give list of match record
Mymodel.objects.get(pk='abcd')
will return single record with matching on primary key value
Mymodel.objects.filter(username='abcd')
将给出匹配记录列表
Mymodel.objects.get(pk='abcd')
将返回与主键值匹配的单个记录