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_querysetmethod 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.objectsreturn? 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.objectsreturns 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.objectsreturns 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')将返回与主键值匹配的单个记录

