关于Django ORM filter方法小结

本文详细介绍了Django ORM中filter的使用方法,包括基本用法、Q对象的应用及跨越多值关联关系时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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')    # 方法二

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

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

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)

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

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

假如只有一个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相似。在跨越多值的关联关系也需要注意,详情可见相关文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值