odoo 里面attrs里面与uid的比较以及替代方案

   最近在使用odoo14的时候,发现odoo的attr里面对于attrs={"invisible":[('state','=','draft'),('sponsor','=',uid)]} 这种写法并不支持,期初以为是自己语法有问题,后来反复查验之后发现不是语法的问题,而是odoo14默认在attrs属性里面不支持对于uid这种变量的解析,所以在执行编译的时候会报错。

那么,如果我们想要实现这种在当前用uid进行比较实现隐藏的效果,应该如何处理呢?

经过我反复试验和验证之后,发现之所以不能通过uid进行比较是因为在odoo的底层控制没有实现对uid这个参数的兼容,所以就导致了这一问题,通过重写代码可以实现这一效果,具体的路径是在:

把代码做如下更改,便可支持兼容uid,

def transfer_node_to_modifiers(node, modifiers, context=None, current_node_path=None):
    # Don't deal with groups, it is done by check_group().
    # Need the context to evaluate the invisible attribute on tree views.
    # For non-tree views, the context shouldn't be given.
    if node.get('attrs'):
        # 解决attrs 不能解析uid属性的问题
        if 'uid' in node.get('attrs'):
            if context.get('uid', False):
                user_id = str(context.get('uid', False))
                attrs = node.get('attrs')
                node.set('attrs', attrs.replace('uid', user_id))
            else:
                # 通过user_id设定初始值来让用户有权限对模块进行升级等操作
                user_id = '1'
                attrs = node.get('attrs')
                node.set('attrs', attrs.replace('uid', user_id))
        modifiers.update(ast.literal_eval(node.get('attrs')))
    if node.get('states'):
        if 'invisible' in modifiers and isinstance(modifiers['invisible'], list):
            # TODO combine with AND or OR, use implicit AND for now.
            modifiers['invisible'].append(('state', 'not in', node.get('states').split(',')))
        else:
            modifiers['invisible'] = [('state', 'not in', node.get('states').split(','))]

    for a in ('invisible', 'readonly', 'required'):
        if node.get(a):
            v = bool(safe_eval.safe_eval(node.get(a), {'context': context or {}}))
            node_path = current_node_path or ()
            if 'tree' in node_path and 'header' not in node_path and a == 'invisible':
                # Invisible in a tree view has a specific meaning, make it a
                # new key in the modifiers attribute.
                modifiers['column_invisible'] = v
                modifiers['tree_invisible'] = v
            elif v or (a not in modifiers or not isinstance(modifiers[a], list)):
                # Don't set the attribute to False if a dynamic value was
                # provided (i.e. a domain from attrs or states).
                modifiers[a] = v

这样修改了之后,便可以支持attrs里面用uid进行表达式的与或计算等。

但是,直接修改底层代码或多或少会有一些风险,所以这个地方,通过研究发现可以使用另外一种替代方案,通过添加一个字段,使用compute属性来判断当前条件是否满足,然后在attrs里面通过计算True 或者 FALSE来判断是否满足。

比如说,我要控制某个按钮只有在申请人在草稿状态下才可见 。那么如何实现呢?

1.  在py文件里面,首先添加一个字段,

is_current_login_approval = fields.Boolean("登录用户是否当前处理人", store=False, compute='_compute_current_approval')

2.实现这个compute方法:

@api.depends('current_approval')
def _compute_current_approval(self):
# 注 我们这里的审批人(current_approval)是一个Many2many
    for flow in self:
        if not flow.current_approval:
            flow.is_current_login_approval = False
            return 
         for record in flow.current_approval:
             if self.env.context.get('uid',None) == record.id:
                  flow.is_current_login_approval = True
                   return
             else:
                  flow.is_current_login_approval = False

3.在attrs里面就可以使用这个compute计算出来的字段来进行计算了

最后实现的效果,就是在to_approve以及approving状态,只有当前审批人可以看到”同意“的按钮。

----------------------------------------------------------------------------------   总结  ---------------------------------------------------------------------------------

目前为止,odoo14原生的代码并不支持在attrs里面,直接使用uid进行计算(domain表达式里面支持),但是可以通过新引入一个compute field 计算出对应的值,然后就可以获取到了,或者您也可以在评估好了

相应的风险之后,直接像上面这样修改底层的代码来更快的实现。

(如果您觉得我的文章对您有用的话,还请动一下您的小手,帮我点一个关注吧)。^_^

----------------------------------------------------------------------------------    end  ---------------------------------------------------------------------------------

你可能感兴趣的:(python,odoo,工作分享,python,odoo,OA)