关于Django ORM filter方法小结

django filter是一个过滤器,相当于SQL的select * from where。 
filter返回一个QuerySet对象,还可以在该对象上继续进行django orm 该有的操作。 
有几点需要注意。我们以该链接的几个model尽心说明。 models链接 
如果我们刷选出Blog表中的name为pcf, tagline包含’django study’的博客。我们可以有这两种简单的filter使用方法。

>>>Blog.objects.filter(name='pcf', tagline__contains='django study')    # 方法一
>>>Blog.objects.filter(name='pcf').filter(tagline__contains='django study') # 方法二
  • 1
  • 2

当然我们还有其余的方法比如使用Q对象,还可以使用原生SQL。在这里简单列一下Q对象使用

>>>from django.db.models import Q
>>>Blog.objects.filter(Q(name='pcf')&Q(tagline__contains='django study'))
  • 1
  • 2

filter 在使用就是这么简单。具体可以参考文档 
本篇博客着重介绍filter在跨越多值的关联关系的使用情况时需要注意的地方。 
跨越多值的关联关系

当你基于ManyToManyField 或反向的ForeignKey 来过滤一个对象时,有两种不同种类的过滤器。考虑Blog/Entry 关联关系(Blog 和 Entry 是一对多的关系)。我们可能想找出headline为“Lennon” 或publish为’2008’年的Entry。或者我们可能想查询包headline为“Lennon” 的Entry以及published为’2008’的Entry。因为实际上有和单个Blog 相关联的多个Entry,所以这两个查询在某些场景下都是有可能并有意义的。

ManyToManyField 有类似的情况。例如,如果Entry 有一个ManyToManyField 叫做 tags,我们可能想找到tag 叫做“music” 和“bands” 的Entry,或者我们想找一个tag 名为“music” 且状态为“public”的Entry。

对于这两种情况,Django 有种一致的方法来处理filter() 调用。一个filter() 调用中的所有参数会同时应用以过滤出满足所有要求的记录。接下来的filter() 调用进一步限制对象集,但是对于多值关系,它们应用到与主模型关联的对象,而不是应用到前一个filter() 调用选择出来的对象。

这些听起来可能有点混乱,所以希望展示一个例子使它变得更清晰。选择所有包含同时满足两个条件的entry的blog,这两个条件是headline 包含Lennon 和发表时间是2008 (同一个entry 满足两个条件),我们的代码是:

>>>Blog.objects.filter(entry__headline__contains='Lennon',entry__pub_date__year=2008)
  • 1

从所有的blog模型实例中选择满足以下条件的blog实例:blog的enrty的headline属性值是“Lennon”,或者entry的发表时间是2008(两个条件至少满足一个,也可以同时满足),我们的代码是:

>>>Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
  • 1

假如只有一个blog 对象同时含有两种entries,其中一种headline 包含“Lennon”而另外一种发表时间是2008,但是没有发表在2008年且headline 包含“Lennon” 的entries。第一个查询不会返回任何blog,第二个查询将会返回一个blog。

在第二个例子中, 第一个filter 限定查询集中的blog 与headline 包含“Lennon” 的entry 关联。第二个filter 又 限定查询集中的blog ,这些blog关联的entry 的发表时间是2008。(译者注:难点在如何理解further这个词!)第二个filter 过滤出来的entry 与第一个filter 过滤出来的entry 可能相同也可能不同。每个filter 语句过滤的是Blog,而不是Entry。

exclude 的使用和filter相似。在跨越多值的关联关系也需要注意,详情可见相关文档

猜你喜欢

转载自www.cnblogs.com/ExMan/p/9443519.html
今日推荐