Django ORM - objects.filter()vs. objects.all()。filter() - 哪一个是首选? [英] Django ORM - objects.filter() vs. objects.all().filter() - which one is preferred?

查看:254
本文介绍了Django ORM - objects.filter()vs. objects.all()。filter() - 哪一个是首选?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很多时候我会看到像

  MyModel.objects.all()。filter(...)

这将返回默认Mananger的QuerySet。首先 all()似乎是相当多余的,因为

  MyMode .objects.filter(...)

提供相同的结果。



但是,这似乎仅为默认管理器保存,因为Django文档中有以下两个语句:



摘录自章节添加额外的管理器方法


自定义管理器方法可以返回任何您想要的内容。它没有
返回一个QuerySet。


all() / code>管理器方法:


all()
返回当前QuerySet(或QuerySet子类)的副本, 。
这可能会在您想要传递
的模型管理器或QuerySet的情况下使用,并对
结果进行进一步过滤。在任何一个对象上调用all()之后,你一定会有一个
QuerySet来处理。


有点像我的矛盾。一方面,Django提供了让管理器方法返回任何首选项的自由,另一方面它需要一个QuerySet用于 all()方法。我知道每个经理都有一个 get_queryset 方法,由 all()调用。但是谁阻止我在我的自定义管理器中覆盖 all()?虽然我同意这样做是不好的设计。




  • 所以就我而言, all()方法不保证返回一个QuerySet。什么是 MyModel.objects 返回?这个语句是否调用 all()?或者`get_queryset()?


  • 你喜欢 MyModel.objects.filter(...) MyModel.objects.all()。filter(...)。如果是这样,为什么?


  • 你有没有遇到过不方便的经理人,会以不良的方式混淆这些方法?

  • b $ b

解决方案

管理员的方法 all()代表们可以在 get_queryset()模型/ manager.py#L132-L133rel =nofollow noreferrer> Django源代码

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

所以这只是一种方法从经理那里获取查询。正如他们在文档中解释的那样,这可以方便地确保您处理查询集而不是经理,因为 MyModel.objects 返回模型管理器。 p>

例如,如果要迭代所有项目,您不能执行以下操作:

  for MyModel.objects中的项目:
#执行项目

因为您无法迭代模型管理器。 all()返回查询集,您可以可以遍历查询集:

  for MyModel.objects.all()中的项目:
#执行项目

通常,您不应该覆盖 all()。您可以覆盖 get_queryset(),但此方法必须返回一个查询。



如果您将使用过滤器方法,如 filter() exclude(),您将已经拥有查询集,因为这些方法被代理到查询器<一>。所以你不需要像 all()。filter()


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

MyMode.objects.filter(...)

delivers the same result.

However, this seems to be save for the default Manager only, because of the following two statements in the Django documentation:

Excerpt fromt the Chapter "Adding extra manager methods"

A custom Manager method can return anything you want. It doesn’t have to return a QuerySet.

Definition of the all() manager method:

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.

This seems a bit like a contradiction to me. On one hand Django offers the freedom to let a manager method return whatever 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.

  • So as far as I can see, the all() method does not guarantee to return a QuerySet. What exactly does MyModel.objects return? Does this statement call all()? or `get_queryset()?

  • Do you prefer MyModel.objects.filter(...) or MyModel.objects.all().filter(...). And if so, why?

  • Have you ever encountered wonky managers that would mess with those methods in a undesirable way?

解决方案

The method all() on a manager just delegates to get_queryset(), as you can see in the Django source code:

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

So it's just a way to get the queryset from the manager. As they explain in the documentation, this can be handy to ensure that you're dealing with a queryset and not a manager, because MyModel.objects returns a model manager.

For example, if you want to iterate over all the items, you can't do this:

for item in MyModel.objects:
    # do something with item

Because you can't iterate over a model manager. all() returns the queryset, you can iterate over a 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 must return a 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().

这篇关于Django ORM - objects.filter()vs. objects.all()。filter() - 哪一个是首选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆