Odoo expression.py domain解析源码(持续更新)
2018-03-23 17:23
633 查看
model.py
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True)domain - 数据筛选条件.
fields - 一个需要展示字段的列表[“field1”,”field2”].
groupby - 一个用来排序的字段列表,也可以用 ‘字段:排序方法’,目前支持日期/时间字段,支持的排序方法有:day’, ‘week’, ‘month’, ‘quarter’ , ‘year’.
offset - 跳过前多少条记录int.
limit - 查询多少条记录.
context - 像lang和time这样的上下文.
orderby - 排序字段列表.
lazy - 如果true,则以第一个字段排序,剩下的字段放在__context上下文中,否则以表里的全部字段排序.
def _where_calc(self, cr, user, domain, active_test=True, context=None)
domain - 数据筛选条件.
active_test - 如果表中有active字段,active_test将筛选active=True的数据记录,但如果在context中传递一个’active_test’:False的参数,active的筛选将被取消.
如果domain中没有对active的字段做限制,在domain的第一位处添加(‘active’, ‘=’, 1),如果domain不存在,但是又存在active_test=True,直接给domain赋值(‘active’, ‘=’, 1).
如果记录中需要显示active=False的记录,例如产品模型,我们可以继承read_group方法,在继承的方法的context里添加active_test = True.这样就可以避免domain被拼接上active = 1的”惨剧”了.
expression.py
class expression(object)
用于解析一个domain表达式,使用真正的波兰表示法,每一个叶子节点都是用的是(field,operator,value)形式.def normalize_domain(domain)
常规化domain - 把精简化的domain写全咯1. domain形式不是tuple或者list例外
2. 如果没有手动的domain,domain默认TRUE_DOMAIN=(1, ‘=’, 1)
3. 循环domain,设置一个expected,我们来试试例子:
[(A),(B)] - result.append((A)) expected = 1 - result.append(&) expected = 0 - result.append((B)) expected = 1 [&,(A),(B)] - result.append(&) expected = 1 - result.append(A) expected = 2 - result.append(B) expected = 1 [|,&,(A),(B),(C)] - result.append(|) expected = 1 - result.append(&) expected = 2 - result.append(A) expected = 3 - result.append(B) expected = 2 - result.append(C) expected = 1 [!,(A),(B),(C)] - result.append(!) expected = 1 - result.append(A) expected = 1 - result.append(B) expected = 1 - result.insert[0:0](&) expected = 0 - result.append(C) expected = 1
4.如果expected最后等于0,那么说明domain格式有问题了.
def combine(operator, unit, zero, domains)
根据操作符,相应的合并domains(简化)1. 针对unit的合并 即 谁和unit合并还是谁 (A) U (1,’=’,1) = (A)
2. 针对zero的合并 即 谁和zero合并还是zero (A) U (1,’=’,1) = zero
3. 针对合并完成的domain,拼接操作符operator*(有效domain单元数量-1)
4. 典型的例子:
operator = ‘&’
unit = (1,’=’,1)
domains = [(A),(B),(C),unit]
return domains = [&]*(3-1)+[(
ad9c
A),(B),(C)]
def AND(domains)
使用combine合并:operator = ‘&’,unit = (1,’=’,1),zero = (1,’=’,0)def OR(domains)
使用combine合并:operator = ‘|’,unit = (1,’=’,0),zero = (1,’=’,1)def is_leaf(element,internal=False)
这个方法就是用来检测,当前的domain单元是否是一个正确的元素形式1. element - 是一个domain元素
2. internal - 如果=True,操作符中加入’inselect’,’not inselect’元素
3. 操作符
TERM_OPERATORS = ('=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike','like', 'not like', 'ilike', 'not ilike', 'in', 'not in','child_of', 'parent_of') INTERNAL_OPS = TERM_OPERATORS + ('<>',) 如果internal=True: INTERNAL_OPS += ('inselect', 'not inselect') TRUE_LEAF = (1, '=', 1) FALSE_LEAF = (0, '=', 1)
检测:
element是列表或者元祖
element元素长度为三
element的操作符在INTERANL_OPS中
element[0]必须是字符串并且有效 或者 element属于(TRUE_LEAF, FALSE_LEAF)
符合则返回True,否则False.
def is_operator(element)
判断domain中的元素是不是操作符operator = DOMAIN_OPERATORS = (NOT_OPERATOR, OR_OPERATOR, AND_OPERATOR) = (‘!’,’|’,’&’)
如果element是字符串 并且 element 在Domain_operators中,那么说明该element就是一个操作符,而不是一个domain的条件对象.
def _quote(to_quote)
to_quote对象一般是一个字符串,如果字符串中没有双引号,那么就给to_quote加上双引号,并返回.def normalize_leaf(element)
如果is_leaf(element)发现domain单元不是一个正确的元素形式,那么直接返回element,否则:将操作符先初始化为小写模式
operator = <> ,将operator转换为!=
operator 是in,not in但是right元素是bool类型,则写_logger.warning警告日志,并且将operator对应的改成=/!=.
operator 是=/!=,但是right元素是 列表或者元组,则写_logger.warning警告日志,并且将operator对应的改成in/not in.
返回(left元素,operator元素,right元素)元组.
def distribute_not(domain)
这里的domain是标准的domain,这个方法主要是处理 不等于 操作符的问题,从Thu和Dony给出的提示信息看,!这样的操作符,不会直接转换为sql的<>,而是对操作对象操作完成后,给整体一个否定.domain没有维护的情况下,return []
如果domain[0]操作符不等于!
def negate(leaf)
这个方法是对domain元素操作符的一个逆向替换,返回一个[!,(left,反向操作符,right)]的列表.
def distribute_negate(domain)
如果对象中存在!操作符,对对应的domain进行反向.
转换前 | 转换后 | 备注 |
---|---|---|
< | >= | |
> | <= | |
<= | > | |
>= | < | |
= | != | |
!= | = | |
in/like/ilike | not in/like/ilike | |
not in/like/ilike | in/like/ilike | |
not like | ||
& | | | |
| | & |
相关文章推荐
- 电商类app源码解析(持续更新)
- faster rcnn源码解析(持续更新中)
- faster rcnn源码解析(持续更新中)
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
- DataReader深入解析:持续更新
- IOS开发--待研究源码(持续添加更新)
- 【10.27更新】 程序员新手福利来了,Android项目源码集合,持续更新。。。
- CListCtrl控件重绘源码---持续更新
- 全面解析hash函数的各种应用(持续更新)
- Android 源码解析之WindowManager更新窗口
- centos从源码搭建ruby环境(持续更新)
- Django源码解析:setting.py
- Android源码编译常见错误(持续更新)
- 源码:我的关于NLP的博客(持续更新中...)
- 300+篇阿里技术热点解析及珍贵技术资料免费下载(文章+PDF+视频_持续更新)
- odoo源码解析-- <2>--启动类加载(2)
- [原创] jQuery1.6.1源码分析系列(持续更新)
- python unittest源码解析三----loader.py之_get_name_from_path(self, path)
- Android子线程更新UI大全及源码解析
- php源码函数汇总(持续更新)