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

原文地址:https://www.cnblogs.com/qianxunman/p/12069343.html

时间: 2024-11-13 10:27:58

odoo fields_view_get的相关文章

(05)odoo数据库和业务操作

以一个例子开头* To-do 向导   # 配置文件       __openerp_.py:         { 'name': 'To-do Tasks Management Assistant',    'description': 'Mass edit your To-Do backlog.',    'author': 'Daniel Reis',    'depends': ['todo_user'],    'data': ['todo_wizard_view.xml'], }  

odoo系统中name_search和name_get用法

自动带出工序和工序序号,两个条件都能搜索,并且两个都带出来显示在前端: # 输入工序序号会自动带出工序名// def name_search(self, cr,user,name='', args=None, operator='ilike', context=None, limit=100): if not args: args=[] args=args[:] ids=[] if name://这两个是搜索条件,根据序号能搜,根据工序名能搜 ids=self.search(cr,user,[(

Odoo实战一:空白模块创建

一:新建模块目录 我们在openerp-server.conf中配置了模块的存放路径,一般为  XXXX\odoo\addons 实际开发时,为了避免与odoo自带模块所混淆,我们一般把自己的模块放到其他文件夹去,甚至,放到odoo所在文件夹之外. 这里,我在odoo同级目录下,新建一个myodoo目录,用于存放我日后自己创建的模块们. 所以,修改openerp-server.conf,在addons_path后面加上路径: addons_path=F:\odoo\odoo-8.0\addons

odoo jQuery is not defined

The steps1.Query your db as this query.select id, create_date, store_fname, datas_fname from ir_attachment where datas_fname like '%.js%';2.Delete records that you found like "web.assets_common.js" "web.assets_backend.js"3.Done. 原文:htt

ODOO中创建website Part-1 创建模块

odoo是使用scaffolding来完成模块创建工作的 scaffolding 中文意思是脚手架 调用方式像这样 $ ./odoo-bin scaffold Academy my-modules odoo-bin是可执行单元 scaffold是要做的动作 academy是模块名字 my-modules是模块所在的文件夹 ps:这个文件夹在 try this odoo-bin scaffold people Peoples 如果没有任何提示,应该就是成功了 在odoo根目录下出现一个people

Google Authentication的实现 - Odoo 安全登录

在前边的一篇文章中,我们提到了利用二次验证增强Odoo登录的可靠性:http://www.cnblogs.com/kfx2007/p/6023991.html 今天我们来具体实现这一步: 后端的实现 我们需要一个地方来存储二次验证的安全码,拓展用户字段: class res_users(models.Model): _inherit='res.users' enable_google_auth = fields.Boolean(u'启用Google两步验证') otp_str = fields.

解决Odoo日期(时间)无效的问题 [转]

环境Server: Ubuntu Kylin 14 + GreenOdoo-7.0-linux64, GreenOdoo-8.0-linux64客户端: winXP+firefox 31 (类似问题发生在Win7+ff30, Win7+ie11)        在安装了Odoo 8之后的试用过程中,遇到日期无效的问题.当初OE 7的时候没有发生过类似问题,期初以为是在版本更新过程中的bug,因此一直没有在意.        如今8.0的已经趋于定型了,试用最新版依然存在这样的问题.于是试了几个系

Odoo MRP 实际成本

Odoo MRP 8 对于 产成品并不支持 实际成本记账 本人开发了一个模块,支持此特性, 可以在 淘宝店铺 购买 https://item.taobao.com/item.htm?_u=85jr9dj42b6&id=535444829332 ? ? ? ? ? ? 安装模块 ? ? 基本设置 ? ? 产品A由 2个原材料组成,物料清单组成如下 ? ? 经由工艺"工艺"制造而成 ? ? 工作中心的成本如下 ? ? 工作中心1 ? ? 工作中心2 工作中心3 ? ? ? ? 产品

(15)odoo配置文件详解

[options]; addons模块的查找路径addons_path = E:\GreenOdoo8.0\source\openerp\addons; 管理员主控密码(用于创建.还原和备份数据库等操作)admin_passwd = admin; 自动重载?auto_reload = None; 用于导入导出的csv文件的默认分隔符csv_internal_sep = ,; data目录, 用于存放session信息.附件data_dir = data; 数据库主机名db_host = 127.