django之Q
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的更多相关文章
- Django中Q查询及Q()对象
问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>> q1 = Entry.objects.filter(headline__st ...
- 浅谈Django的Q查询以及AngularJS的Datatables分页插件
使用Q查询,首先要导入Q模块: from django.db.models import Q 可以组合使用&,|操作符用于多个Q的对象,产生一个新的Q对象,Q对象也可以用~操作符放在前面表示否 ...
- Django中Q搜索的简单应用
本节涉及: 1.Q搜索在前后端的设计 2.Django中Queryset对象的序列化(由后端扔给前端的数据必然会经过序列化) 3.前端动态地构造表格以便显示(动态创建DOM对象) 思路: 用户通过前端 ...
- Django orm Q查询补充
Q的简单用法 from django.db.models import Q q = Q() q.children.append(("username", "lyj&quo ...
- Django Q对象
使用Q 对象进行复杂的查询¶ filter() 等方法中的关键字参数查询都是一起进行“AND” 的. 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象. Q 对象 (django.db ...
- python 之 Django 小案例
一, F Q # F 使用查询条件的值 # # from django.db.models import F # models.Tb1.objects.update(num=F('num')+1) ...
- Python之路【第二十一篇】Django ORM详解
ORM回顾 关系对象映射(Object Relational Mapping,简称ORM). django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表. 对于ORM框 ...
- django manytomany
转载:http://my.oschina.net/u/572994/blog/105280 例如有如下模型 models.py ? 1 2 3 4 5 6 7 from django.db impor ...
- django的前后的结合,search搜索功能案例
利用django的Q()功能可以很好的展开搜索功能 假设我要做个这样的搜索功能
随机推荐
- Windows下利用TortoiseSVN搭建本地SVN服务器
写在前面: 安装TortoiseSVN时,图中这步要选择,才能同时安装后面需要的svnserve.exe 环境说明: Win 7 TortoiseSVN 1.7 搭建步骤: 0. 新建一个目录,做&q ...
- Git初级
一,安装git 一键安装 Mac 或 Windows. 二,下载一个工具书 Git 命令手册 free Git cheat sheet 三,安装完成之后需要先配置两个基本配置:用户名和邮箱 $ git ...
- 客户端负载均衡Feign之三:Feign补充
在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Ap ...
- 学习笔记之Swagger
World's Most Popular API Framework | Swagger https://swagger.io/ Swagger is the world’s largest fram ...
- Ring0 - 链表
//一般驱动层不使用数据结构,一般Ring3层 双向链表可以将链表形成一个环.BLINK指针指向前一个元素,FLINK指针指向下一个元素.typedef struct _LIST_ENTRY { st ...
- [UE4]UI之间传递数据
通过创建对方UI类型的变量引用,初始本控件时赋值该变量,就可以对方UI内的方法了.
- Linux上面的MTU含义
问题场景描述: 最近在搞一个很菜的程序--FTP上传文件. 但是这个 很菜的程序搞的我脑袋疼了 半个月. 在linux上面部署了我的程序,上传文件在1KB以下顺利上传,但是1KB以上上传不上去. 程序 ...
- Find the peace with yourself
The purpose of being mature is to find the real calm and peace with yourself. Or you can say the tur ...
- dict函数
增 fromkeys(iterable, value) 用可迭代对象生成键,创建默认值相同的字典(value默认None) 删 pop(k) 通过k来删除字典元素, 找不到就会报错, 返回被删除字典元 ...
- Apache poi简介及代码操作Excel
一.简介 在我们进行企业的系统开发时,难免会遇到网页表格和Excel之间的操作问题(POI是个不错的选择) Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序 ...