def _add_q(self, q_object, used_aliases, branch_negated=False,
current_negated=False, allow_joins=True, split_subq=True):
"""
Adds a Q-object to the current filter.
"""
connector = q_object.connector
current_negated = current_negated ^ q_object.negated#或,判断要不要取反
branch_negated = branch_negated or q_object.negated
target_clause = self.where_class(connector=connector,
negated=q_object.negated)
joinpromoter = JoinPromoter(q_object.connector, len(q_object.children), current_negated)
for child in q_object.children:#promotion促销,提升
if isinstance(child, Node):
child_clause, needed_inner = self._add_q(
child, used_aliases, branch_negated,
current_negated, allow_joins, split_subq)
joinpromoter.add_votes(needed_inner)
else:
child_clause, needed_inner = self.build_filter(
child, can_reuse=used_aliases, branch_negated=branch_negated,
current_negated=current_negated, connector=connector,
allow_joins=allow_joins, split_subq=split_subq,
)
joinpromoter.add_votes(needed_inner)
if child_clause:
target_clause.add(child_clause, connector)
needed_inner = joinpromoter.update_join_types(self)
return target_clause, needed_inner
class Node(object):
"""
A single internal node in the tree graph. A Node should be viewed as a
connection (the root) with the children being either leaf nodes or other
Node instances.
"""
# Standard connector type. Clients usually won't use this at all and
# subclasses will usually override the value.
default = 'DEFAULT' def __init__(self, children=None, connector=None, negated=False):
"""
Constructs a new Node. If no connector is given, the default will be
used.
"""
self.children = children[:] if children else []
self.connector = connector or self.default
self.negated = negated # We need this because of django.db.models.query_utils.Q. Q. __init__() is
# problematic, but it is a natural Node subclass in all other respects.
@classmethod
def _new_instance(cls, children=None, connector=None, negated=False):
"""
This is called to create a new instance of this class when we need new
Nodes (or subclasses) in the internal code in this class. Normally, it
just shadows __init__(). However, subclasses with an __init__ signature
that is not an extension of Node.__init__ might need to implement this
method to allow a Node to create a new instance of them (if they have
any extra setting up to do).
"""
obj = Node(children, connector, negated)
obj.__class__ = cls
return obj def __str__(self):
if self.negated:
return '(NOT (%s: %s))' % (self.connector, ', '.join(str(c) for c
in self.children))
return '(%s: %s)' % (self.connector, ', '.join(str(c) for c in
self.children)) def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self) def __deepcopy__(self, memodict):
"""
Utility method used by copy.deepcopy().
"""
obj = Node(connector=self.connector, negated=self.negated)
obj.__class__ = self.__class__
obj.children = copy.deepcopy(self.children, memodict)
return obj def __len__(self):
"""
The size of a node if the number of children it has.
"""
return len(self.children) def __bool__(self):
"""
For truth value testing.
"""
return bool(self.children) def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self) def __contains__(self, other):
"""
Returns True is 'other' is a direct child of this instance.
"""
return other in self.children def add(self, data, conn_type, squash=True):
"""
Combines this tree and the data represented by data using the
connector conn_type. The combine is done by squashing the node other
away if possible. This tree (self) will never be pushed to a child node of the
combined tree, nor will the connector or negated properties change. The function returns a node which can be used in place of data
regardless if the node other got squashed or not. If `squash` is False the data is prepared and added as a child to
this tree without further logic.
"""
if data in self.children:#节点在孩子中,直接返回
return data
if not squash:#不挤进,追加到孩子中
self.children.append(data)
return data
if self.connector == conn_type:#连接子相同
# We can reuse self.children to append or squash the node other.
if (isinstance(data, Node) and not data.negated
and (data.connector == conn_type or len(data) == 1)):
# We can squash the other node's children directly into this
# node. We are just doing (AB)(CD) == (ABCD) here, with the
# addition that if the length of the other node is 1 the
# connector doesn't matter. However, for the len(self) == 1
# case we don't want to do the squashing, as it would alter
# self.connector.
self.children.extend(data.children)#加入孩子
return self
else:
# We could use perhaps additional logic here to see if some
# children could be used for pushdown here.
self.children.append(data)
return data
else:#连接字不相同,新创建一个node
obj = self._new_instance(self.children, self.connector,
self.negated)
self.connector = conn_type
self.children = [obj, data]
return data def negate(self):
"""
Negate the sense of the root connector.
"""
self.negated = not self.negated

django之Q的更多相关文章

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

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

  2. 浅谈Django的Q查询以及AngularJS的Datatables分页插件

    使用Q查询,首先要导入Q模块: from django.db.models import Q 可以组合使用&,|操作符用于多个Q的对象,产生一个新的Q对象,Q对象也可以用~操作符放在前面表示否 ...

  3. Django中Q搜索的简单应用

    本节涉及: 1.Q搜索在前后端的设计 2.Django中Queryset对象的序列化(由后端扔给前端的数据必然会经过序列化) 3.前端动态地构造表格以便显示(动态创建DOM对象) 思路: 用户通过前端 ...

  4. Django orm Q查询补充

    Q的简单用法 from django.db.models import Q q = Q() q.children.append(("username", "lyj&quo ...

  5. Django Q对象

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

  6. python 之 Django 小案例

    一, F  Q # F 使用查询条件的值 # # from django.db.models import F # models.Tb1.objects.update(num=F('num')+1) ...

  7. Python之路【第二十一篇】Django ORM详解

    ORM回顾 关系对象映射(Object Relational Mapping,简称ORM). django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表. 对于ORM框 ...

  8. django manytomany

    转载:http://my.oschina.net/u/572994/blog/105280 例如有如下模型 models.py ? 1 2 3 4 5 6 7 from django.db impor ...

  9. django的前后的结合,search搜索功能案例

    利用django的Q()功能可以很好的展开搜索功能 假设我要做个这样的搜索功能

随机推荐

  1. intellij idea 设置 Error 提示颜色修改

    File--->Settings --->Editor --->ColorScheme--->General --->Errors and Warning--->E ...

  2. nginx简单学习(tomcat)

    一.负载均衡的简单配置 1.下载nginx 2.tomcat*2 配置不同的端口用于正常启动,在jsp中<%= session.getId()%>可以查看jSessionId,tomcat ...

  3. mysql 数据库排序规则

    MySQL中的排序规则.在新建MySQL数据库或表的时候经常会选择字符集和排序规则.数据库用的字符集大家都知道是怎么回事,那排序规则是什么呢? 排序规则:是指对指定字符集下不同字符的比较规则.其特征有 ...

  4. LeetCode——1. Two Sum

    一.题目链接:https://leetcode.com/articles/two-sum/ 二.题目大意: 给定一个int型数组A和int值a,要求从A中找到两个数,使得这两个数值的和为a:返回结果为 ...

  5. Windows下利用TortoiseSVN搭建本地SVN服务器

    写在前面: 安装TortoiseSVN时,图中这步要选择,才能同时安装后面需要的svnserve.exe 环境说明: Win 7 TortoiseSVN 1.7 搭建步骤: 0. 新建一个目录,做&q ...

  6. noi2017 day2t2

    设a[i]为当前方案中第 1..i 天变质的蔬菜有几个,b[i]为前i天至少能卖出几个,方案可行的条件是对任意i有a[i]<=b[i],用线段树维护b[i]-a[i]. 从小到大枚举天数,枚举到 ...

  7. 【IIS错误】未能加载文件或程序集“AAAAA”或它的某一个依赖项。试图加载格式不正确的程序。

    未能加载文件或程序集“AAAAA”或它的某一个依赖项.试图加载格式不正确的程序. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的 ...

  8. PAT 乙级 1076 Wifi密码 (15)

    下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用wifi,又怕耽误亲们的学习,现将wifi密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请同学们自己作答,每两日一换.谢 ...

  9. CentOS7安装配置PostgreSQL9.6

    本文涉及CentOS7下PostgreSQL9.6的yum安装,访问配置及简单使用. 一.验证环境 1. 操作系统 CentOS-7-x86_64-Everything-1511 2. Postgre ...

  10. MySQL 开启和查看bin-log日志

    1.5.7版本前修改my.cnf文件,添加log-bin=my-bin(my.cnf的位置根据自己安装的路径查看)# vi /usr/local/mysql/my.cnflog-bin=my-bin  ...