• odoo fields_view_get


    odoo fields_view_get创建动态视图方法


    odoo  fields_view_get方法是一个比较有用比较灵活的广泛,如果使用得当,可以做到一些常规方法无法实现的功能,本文列举若干种用法。

    openerp的视图结构是以XML的格式存放于ir.ui.view表中,属于静态格式,设计之后就固定,

    但可以通过在model中重写fields_view_get函数,在视图加载时修改arch属性,动态修改视图的结构

    Odoo 开发中经常会遇到这样的需求,对象中根据条件是否显示一个字段。比如如果不是创建人,不不显示客户的联系方式,Odoo 中如何实现呢?<一>domain在 odoo 中可以根据对象字段的值或者关系确定是否显示一个字段。

    动态 domain 的例子,根据选择结构确定字段是否显示。还有一种方式是,可以在 view 中,根据 states 的值确定字段是否显示。

    view 的state

    动态视图

    用法一、 修改field的属性:

        def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
            #override of fields_view_get in order to replace the name field to product template
            if context is None:
                context={}
            res = super(product_product, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
            #check the current user in group_product_variant
            group_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'product', 'group_product_variant')[1]
            obj = self.pool.get('res.groups').browse(cr, uid, group_id, context=context)
            doc = etree.XML(res['arch'])
            if view_type == 'form':
                if obj and uid in [x.id for x in obj.users]:
                    for node in doc.xpath("//field[@name='name']"):
                        node.set('invisible', '1')
                        node.set('required', '0')
                        setup_modifiers(node, res['fields']['name'])     #这行必须要有
                    for node in doc.xpath("//label[@string='Product Name']"):
                        node.set('string','Product Template')
                else:
                    for node in doc.xpath("//field[@name='product_tmpl_id']"):
                        node.set('required','0')
                        setup_modifiers(node, res['fields']['product_tmpl_id'])     #这行必须要有
                    for node in doc.xpath("//field[@name='name']"):
                        node.set('invisible', '0')
                        setup_modifiers(node, res['fields']['name'])     #这行必须要有
                    for node in doc.xpath("//label[@string='Product Template']"):
                        node.set('string','Product Name')
            res['arch'] = etree.tostring(doc)
            return res

    1

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):  
            if context is None:context = {}  
            res = super(rhwl_gene, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)  
            if res['type']=="form":  
                id = res['id']  
                //根据id去取得资料,并进行判断  
                if 条件成立:  
                    doc = etree.XML(res['arch'])  
                    doc.xpath("//form")[0].set("edit","false")  
                    res['arch']=etree.tostring(doc)  
            return res 

    2

    def fields_view_get(self, cr, uid, view_id=None,view_type='form',context=None,toolbar=False,submenu=False):
            ip_obj = self.pool.get('hr.rule.input')
            res = super(hr_inputs_editor,self).fields_view_get(cr,uid,view_id,view_type,context,toolbar,submenu)
            if view_type=='form':
                treev = res['fields']['line_ids']['views']['tree']
                doc = etree.XML(treev['arch'])
                for node in doc.xpath("/tree/field"):
                    name = node.get('name',False)
                    if name.startswith('value'):
                        name = name.replace('value','input') + '_code'
                        cd = context.has_key(name) and context[name] or False
                        if cd:
                            ip_ids = ip_obj.search(cr,uid,[('code','=',cd)],limit=1,context=context)
                            if ip_ids:
                                text = ip_obj.read(cr,uid,ip_ids,['name'])[0]['name']
                                node.set('string',text)
                        else:
                            node.set('modifiers','{"tree_invisible":true}')
                treev['arch'] = etree.tostring(doc)
            return res

    用法二、根据条件限制view是否可编辑(网上曾经有个人提出在指定日期内可以编辑,也可以参考下面的代码实现)

    @api.model
    def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
        if view_type == 'form':
            res['arch'] = self.fields_view_get_address(res['arch'])
            record = self.env['crm.lead'].browse(self._context.get('params').get('id'))
            # restrict modification and deletion of child ids
            if record.parent_id:
                res['arch'] = res['arch'][:6] + 'edit="false" delete="false" ' + res['arch'][6:]
            elif record.stage_id.id == 4:  # restrict edition of Purchased Lead
                res['arch'] = res['arch'][:6] + 'edit="false" ' + res['arch'][6:]
        return res

    用法三、给视图动态增加field,下面的代码是给某视图动态增加一个field (product_id):

    @api.model
    def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
        doc = etree.XML(res['arch'])
        summary = doc.xpath("//field[@name='product_id']")
        if len(summary):
            summary = summary[0]
            summary.addnext(etree.Element('field', {'name': 'product_id', 
                                                    'string':'title of new field',
                                                    'nolabel':'0',
                                                    }))
        res['arch'] = etree.tostring(eview) 
        return res

    用法四、给视图增加一个page(跟用法三有些类似):

    class product_product(osv.osv):
      _inherit = 'product.product'
       
      def fields_view_get(self, view_id=None, view_type='form', toolbar=False,submenu=False):
        """
        Changes the view dynamically
        @param self: The object pointer.
        @return: New arch of view.
        """
        ret_val = super(product_product, self).fields_view_get(view_id, view_type, toolbar,submenu)
        if view_type == 'form':
          doc = etree.XML(ret_val['arch'], parser=None, base_url=None)
           
          #要加入到视图里的page
          _moves_arch_lst = """
            <page string='Feature'>
            </page>
          """
          first_node = doc.xpath("//page[@string='Sales']")
          if first_node and len(first_node)>0:  
            #先把_moves_arch_lst转成XML Node,然后加到查找到node中
            feature_page = etree.XML(_moves_arch_lst)
            first_node.addnext(feature_page)            
            ret_val['arch'] = etree.tostring(doc, encoding="utf-8")
        return ret_val

    动态修改field的domain:

    class account_voucher(osv.osv):
        _inherit = 'account.voucher'
        def fields_view_get(self, view_id=None, view_type=False, toolbar=False, submenu=False):
            """
                Add domain 'allow_check_writting = True' on journal_id field 
                and remove 'widget = selection' on the same field 
                because the dynamic domain is not allowed on such widget
            """
            if not context: context = {}
            res = super(account_voucher, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
            doc = etree.XML(res['arch'])
            nodes = doc.xpath("//field[@name='journal_id']")
             
            # 检查context是否有指定的标志(write_check)
            if context.get('write_check', False) :
                for node in nodes:
                 
                    # 动态修改 journal_id 这个field的domain
                    node.set('domain', "[('type', '=', 'bank'), ('allow_check_writing','=',True),('your_field','=','value')]")
                     
                    # 把 widget 清空,原因在上面已经说了
                    node.set('widget', '')
                     
                res['arch'] = etree.tostring(doc)
            return res




    原文链接: http://www.odoogo.com/post/87/#comment-block
  • 相关阅读:
    (一)Python入门-2编程基本概念:18字符串-驻留机制-内存分析-字符串同一判断-值相等判断
    (一)Python入门-2编程基本概念:07内置数据类型-基本算数运算符
    (一)Python入门-2编程基本概念:08整数-不同进制-其他类型转换成整数
    (一)Python入门-2编程基本概念:09浮点数-自动转换-强制转换-增强赋值运算符
    (一)Python入门-2编程基本概念:10时间表示-unix时间点-毫秒和微妙-time模块
    (一)Python入门-2编程基本概念:11布尔值-比较运算符-逻辑运算符及短路问题
    (一)Python入门-2编程基本概念:12同一运算符-整数缓存问题
    (一)Python入门-2编程基本概念:01程序的构成
    (一)Python入门-2编程基本概念:02对象的基本组成和内存示意图
    有关位运算的基础知识总结
  • 原文地址:https://www.cnblogs.com/qianxunman/p/12069343.html
Copyright © 2020-2023  润新知