您的位置:首页 > 大数据 > 人工智能

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/ilikenot in/like/ilike
not in/like/ilikein/like/ilike
not like
&|
|&
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: