使用Q 对象进行复杂的查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象

Q 对象 (django.db.models.Q) 对象用于封装一组关键字参数。这些关键字参数就是上文“字段查询” 中所提及的那些。

例如,下面的Q 对象封装一个LIKE 查询:

  1. from django.db.models import Q
  2. Q(question__startswith='What')

Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。

例如,下面的语句产生一个Q 对象,表示两个"question__startswith" 查询的“OR” :

  1. Q(question__startswith='Who') | Q(question__startswith='What')

它等同于下面的SQL WHERE 子句:

  1. WHERE question LIKE 'Who%' OR question LIKE 'What%'

你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:

  1. Q(question__startswith='Who') | ~Q(pub_date__year=2005)

每个接受关键字参数的查询函数(例如filter()exclude()get())都可以传递一个或多个Q 对象作为位置(不带名的)参数。如果一个查询函数有多个Q 对象参数,这些参数的逻辑关系为“AND"。例如:

  1. Poll.objects.get(
  2. Q(question__startswith='Who'),
  3. Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
  4. )

... 大体上可以翻译成这个SQL:

  1. SELECT * from polls WHERE question LIKE 'Who%'
  2. AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:

  1. Poll.objects.get(
  2. Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
  3. question__startswith='Who')

... 是一个合法的查询,等同于前面的例子;但是:

  1. # INVALID QUERY
  2. Poll.objects.get(
  3. question__startswith='Who',
  4. Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

... 是不合法的。

另见

Django 单元测试中的OR 查询示例演示了几种Q 的用法。

Django的Q对象实现的源码中:

  1. # 位于/django/db/models/query_utils.py
  2. class Q(tree.Node):
  3. """
  4. Encapsulates filters as objects that can then be combined logically (using
  5. & and |).
  6. """
  7. # Connection types
  8. AND = 'AND'
  9. OR = 'OR'
  10. default = AND
  11. def __init__(self, *args, **kwargs):
  12. super(Q, self).__init__(children=list(args) + kwargs.items())
  13. def _combine(self, other, conn):
  14. if not isinstance(other, Q):
  15. raise TypeError(other)
  16. obj = type(self)()
  17. obj.add(self, conn)
  18. obj.add(other, conn)
  19. return obj
  20. def __or__(self, other):
  21. return self._combine(other, self.OR)
  22. def __and__(self, other):
  23. return self._combine(other, self.AND)
  24. def __invert__(self):
  25. obj = type(self)()
  26. obj.add(self, self.AND)
  27. obj.negate()
  28. return obj

传Q对象,构造搜索条件

首先还是需要导入模块:

  1. from django.db.models import Q

传入条件进行查询:

  1. q1 = Q()
  2. q1.connector = 'OR'
  3. q1.children.append(('id', 1))
  4. q1.children.append(('id', 2))
  5. q1.children.append(('id', 3))
  6. models.Tb1.objects.filter(q1)

合并条件进行查询:

  1. con = Q()
  2. q1 = Q()
  3. q1.connector = 'OR'
  4. q1.children.append(('id', 1))
  5. q1.children.append(('id', 2))
  6. q1.children.append(('id', 3))
  7. q2 = Q()
  8. q2.connector = 'OR'
  9. q2.children.append(('status', '在线'))
  10. con.add(q1, 'AND')
  11. con.add(q2, 'AND')
  12. models.Tb1.objects.filter(con)

Django Q对象的更多相关文章

  1. Django中Q查询及Q()对象

    问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>> q1 = Entry.objects.filter(headline__st ...

  2. Django运算表达式与Q对象/F对象

    Django运算表达式与Q对象/F对象 1 模型查询 概述: 1 查询集:表示从数据库中获取的对象的集合 2 查询集可以有多个过滤器,通过 逻辑运算符连接 3 过滤器就是一个函数,基于所给的参数限制查 ...

  3. Python自动化之django orm之Q对象

    Python自动化之django orm之Q对象 什么是Q对象? Encapsulates filters as objects that can then be combined logically ...

  4. 在Django中使用Q()对象

    转载于:  http://www.smallerpig.com/1000.html 问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>& ...

  5. django的F和Q对象

    F表达式和Q表达式: # 示例模型如下 class Book(models.Model): """图书模型""" name = models ...

  6. 【Django】Django中的模糊查询以及Q对象的简单使用

    Django中的模糊查询: 需要做一个查找的功能,所以需要使用到模糊查询. 使用方法是:字段名加上双下划线跟上contains或者icontains,icontains和contains表示是否区分大 ...

  7. 【转】Django之Model层的F对象,Q对象以及聚合函数

    转自:https://blog.csdn.net/wsy_666/article/details/86692050 一.F对象: 作用:用于处理类属性(即model的某个列数据),类属性之间的比较.使 ...

  8. Django学习路18_F对象和Q对象

    F 对象: 可以使用模型的 A 属性和 B 属性进行比较 写法: 需要的数据对象 = 数据表(类名).objects.filter(列名__条件=F('列名2')) 需求: 查看男生数量比女生少 的公 ...

  9. Django中F对象,Q对象与运算符

    在Django的模型中F对象与Q对象比较常用的,所以单独说一下: F对象 F对象位于django.dc.models模板下,使用的时候记得首先导入!!! 作用:F对象主要用于当模型的字段A与字段B进行 ...

随机推荐

  1. 天梯赛 L2-024. (并查集) 部落

    题目链接 题目描述 在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈.我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查 ...

  2. bootstrap-table 应用

    更多内容推荐微信公众号,欢迎关注: 前端代码:js初始化表格,使用服务器端分页:<!DOCTYPE html> <html> <head> <meta cha ...

  3. 【疑点】<p></p>标签为什么不能包含块级标签?还有哪些特殊的HTML标签?

    最近,在码代码的时候,就是下面的这段代码,我犯了一个很不起眼,但犯了就致命的BUG. <body> <p> <ol> <li>Hello</li& ...

  4. Servlet笔记1--概述

    JavaEE概述及系统架构分析: (1) JavaEE概述: (2) 系统架构分析:

  5. Linux内核抢占实现机制分析【转】

    Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...

  6. oracle用plsql查询死锁

    1. 点击plsql 工具(tool),点击会话(session) 2.点击锁,可以看到锁的session

  7. 简单的搭mysql开发环境

    所需软件  环境win8 64bit mysql5.7.16winx64.zip mysql-workbench-community-6.3.5-win32.zip 安装完了之后到mysql/bin下 ...

  8. vue全面介绍--全家桶、项目实例

    简介 “简单却不失优雅,小巧而不乏大匠”. 2016年最火的前端框架当属Vue.js了,很多使用过vue的程序员这样评价它,“vue.js兼具angular.js和react.js的优点,并剔除了它们 ...

  9. 数据库——mysql如何获取当前时间

    1.1 获得当前日期+时间(date + time)函数:now() 除了 now() 函数能获得当前的日期时间外,MySQL 中还有下面的函数: current_timestamp() curren ...

  10. 从bind函数看js中的柯里化

    以下是百度百科对柯里化函数的解释:柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.概念太抽象,可能 ...