问题背景
之前用django的时候,数据库这一块也没有涉及到比较复杂一点的查询,一般就是一个filter()或者一个get()就搞定了,前几天做一个可视化的项目时,遇到了多条件复合查询,看了下文档,django的orm还是挺好用的,Q()函数可以解决这个问题。
比如我要查询id为1或者id为2的一个数据,在filter里面,是不能够这么直接来的:,只能使用Q函数。为了更深入地理解Q函数,我参考官方文档,整理一下它的用法。filter(id=1,id=2)
文档位置:https://docs.djangoproject.com/en/1.9/topics/db/queries/#complex-lookups-with-q-objects
django中Q()函数的介绍
如果你需要进行复杂的查询(比如or条件),你可以使用Q对象。
Q对象是用来封装查询参数的,比如,它可以仅仅用来封装单独一个like查询:
from django.db.models import Q Q(question__startswith='What')
Q函数可以通过逻辑符号连接
Q对象可以和&
、|
这两个符号一起来使用,即and和or。下面这个例子就用or将两个查询组合在了一起:
Q(question__startswith='Who') | Q(question__startswith='What')
相当于以下sql语句:
WHERE question LIKE 'Who%' OR question LIKE 'What%'
另外,还可以使用非符号~
,比如:
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
Q函数用于数据库查询
以上介绍了Q的组合方法,那么怎么把它应用到数据库的查询呢?一般而言,可以把它们放到filter()
,get()
或者exclude()
里面,比如:
Poll.objects().filter(Q(question__startswith='Who') | ~Q(pub_date__year=2005))
Q函数和关键字参数混合使用
另外,Q对象还可以和关键字参数一起使用,不过Q一定要放在前面,以下是正确例子:
Poll.objects.get( Q(question__startswith='Who'), Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) )
相当于sql查询语句如下:
SELECT * from polls WHERE question LIKE 'Who%' AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
关键字参数放在前面是错误的用法!!如下是错误的!
# 错误用法 Poll.objects.get( question__startswith='Who', Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) )
我的实践
我喜欢这样来用Q对象。先在外面将条件组合好,然后再传入filter()
、get()
或者exclude()
里面,代码片段如下:
from django.db.models import Q my_filter = Q() my_filter = my_filter | Q(id=1) my_filter = my_filter | Q(name="lipengfei") result = People.objects.filter(my_filter)