zoukankan      html  css  js  c++  java
  • Odoo中的模型继承、视图继承、Qweb模板继承详解

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826114.html

        在实际开发过程中,经常会遇到需要修改Odoo原生逻辑的情况。然而,直接修改Odoo底层代码,不利于后面odoo版本迭代时替换。因此,在不改变底层对象的时候添加新的功能,就显得十分重要。

        Odoo提供继承机制来实现这个目的,继承修改可以发生:Python代码和XML视图、Qweb模版上

    一:模型继承

            1:模型修改

    # -*- coding: utf-8 -*-
    from odoo import models, fields, api
    class Sub(models.Model):
        _inherit = 'Root'  //通过_inherit属性来继承父模型
        newCol=fields.XX....  //在下面添加新字段即可。

          1)添加字段

            如上,直接定义新字段即可。

           2)修改现有字段

            为了改变现有字段的属性,只需再次定义该同名字段,需要修改的属性显式重写即可,会保留未修改的所有其他未在此处明确使用的字段的属性。

            3)添加方法

            添加新方法很简单:只需在继承类中声明新的函数。

            4)修改方法

            扩展或更改现有逻辑,可以通过声明具有完全相同名称的方法来覆盖相应的方法

            新方法将替换前一个方法,它可以只是扩展继承类的代码,使用Python的super()方法来调用父方法。然后,可以在调用super()方法之前和之后,在原有逻辑周围添加新逻辑

     

          2:模型继承的方式

            1)类继承

             扩展类中没有_name属性,因为它继承了父类的_name。对现有模型的扩展, 添加新功能,都将添加到现有模型中,不会创建新模型。 因此,在odoo中,根据_name唯一确定这个模型时找到的就是扩展后的类。(如上面添加字段是类继承)

            2)原型继承(带name继承,创建新的表)

              我们想使用具有不同于父模型的值的_name属性,我们将获得一个新模型重用来自继承的特性,但是具有自己的数据库表和数据。其实就是把继承的类的功能特性拷贝给新的模型使用,并不改变被继承模型。

              复制意味着被继承的方法和字段也将在继承模型中可用。 对于字段,这意味着它们也将被创建并存储在目标模型的数据库表中。 原始(继承)和新(继承)模型的数据记录保持不相关,只有定义是共享的。

            3)代理继承(委托继承)【以成员变量的形式把父类对象包含进来】

              使用_inherits属性,它允许一个模型以透明的方式包含其他模型。通过字典映射继承模型与字段的关系,并关联它们

              通俗解释:(相当于成员变量:引用一个外部的类对象赋值给这个模型的一个成员,但是对象的值是保存在被引用的类的数据库表中的。但是在当前类通过成员修改了变量值,则会同步到被引用的类的数据库表中)

              优点是不需要在几个表之间重复数据结构,例如地址。 任何需要包含地址的新模型都可以将其委派给嵌入式合作伙伴模型。 如果在合作伙伴地址字段中引入了修改,则这些修改会立即提供给嵌入它的所有模型!

    二:视图继承

              表单,列表和搜索视图是使用arch XML结构定义的,要扩展视图,我们需要一种方法来修改这个XML。 这意味着需要定位XML中的元素位置,然后在这些位置引入修改

              对于XML,在其中定位元素的最好方法是使用XPath表达式,如果XPath表达式匹配到多个元素,只有第一个元素会被修改

              因此,表达式应该使用独特的属性以使其指定尽可能具体,使用name属性是确保我们找到扩展点的确切xml元素的最简单方法。 因此,在我们的视图XML元素上定义name属性是很重要的。

              Xpath表达式的格式:expr="//标签名[@属性]='属性值'"    意思是:找到  属性=属性值  的标签的位置。

              下面是一个写在arch中的实现在is_done字段之前添加date_deadline字段的具体例子:

    <xpath expr="//field[@name]='is_done'" position="before"> //expr属性值的意思是:找到<filed name="is_done"/>的标签
           <field name="date_deadline" />
    </xpath> 

               Odoo为此提供了快捷符号,因此大多数时候我们可以完全避免XPath语法。 我们仅使用要定位的元素的特定属性及定位类型相关信息就可以了。

     <field name="is_done" position="before">
          <field name="date_deadline" />
      </field> 

           【如果字段在同一视图中多次出现,则应始终使用XPath语法。】

             position属性是可选的:

    after:将内容添加到父元素之中,匹配的节点之后。
    before:添加内容在匹配节点之前。
    inside(默认值):匹配节点内的追加内容。
    replace:替换匹配的节点。如果使用空内容,它将删除该匹配的元素。
    attributes:修改匹配元素的XML属性。在元素内容使用<attribute name =“attr-name”>实现给标签设置新属性值attr-name。
    1.如果<attribute></attribute>之间有值,就在匹配的节点上添加以name命名的、以内容主体为值的属性或是修改原同名属性值。
    2.如果
    <attribute></attribute>没有值,就将匹配节点上名字为name的属性删除,如果原节点上没有对应的属性,抛出一个错误。

           下面是视图继承的模版写法:

            1)扩展表单视图

    <record id="view_form_模块名_inherited" model="ir.ui.view">
           <field name="name">模块名_extension</field>
           <field name="model">模型名</field>
           <field name="inherit_id" ref="模块_模型.被继承的form表单id"/>
           <field name="arch" type="xml"> //在arch中进行扩展操作:定位—>插入/修改
               <field name="定位标签name" position="在标签的哪里进行扩展">
                   <field ......> //扩展内容
               </field>
           </field>
    </record> 

              2)扩展列表视图

       <record id="view_tree_模型名_inherited" model="ir.ui.view">
           <field name="name">模型名 extension</field>
           <field name="model">模型</field>
           <field name="inherit_id" ref="被继承的tree视图id"/>
           <field name="arch" type="xml">//在arch中进行扩展
                <field name="定位标签name" position="扩展位置"> 
                    <field ....进行扩展 />
                </field>
           </field>
        </record>

                3)扩展搜索视图

      <record id="view_filter_模型名_inherited" model="ir.ui.view">
           <field name="name">xxxextension</field>
           <field name="model">模型名</field>
           <field name="inherit_id" ref="被继承的搜索视图id"/>
           <field name="arch" type="xml"> //下面进行定位、扩展举例
               <field name="定位的标签name" position="after">
                   //引入的修改,可以是增加过滤field,也可以定义 filter
               </field> 
           </field>
        </record> 

               

    三:Qweb继承

            Qweb继承是通过qweb语法来书写的。但是思路一致:定位——>引入扩展

            Qweb文件继承分两种:Qweb视图类型的文件和data类型的文件,二者继承修改的方式不同。

         1:视图类型的qweb文件继承

           视图类型的qweb文件,一般定义的都是一些视图模板,template中的内容大多用html+qweb语句编写,如widget的视图定义、odoo中各个界面的定义。

            1)在statc/xml目录下新建一个xml文件

            2)编写以下内容

    <?xml version="1.0" encoding="UTF-8"?>
    
    <template id="唯一的id" xml:space="preserve">
    
        <t t-extend="要继承扩展的template的name属性值">
            <t t-jquery="使用选择器来定位" t-operation="相当于position">
                //扩展的内容,一般用html语法+qweb语句编写
            </t>
        </t>
    
    </template>

             3)在manifest文件中,配置到qweb配置项:

    "qweb": [
            "static/src/xml/qweb_file.xml",
        ],

         2:data类型的qweb文件继承

            data类型的qweb文件,一般是一些辅助界面qweb的文件,大多用于定义、引入css文件等,多处于view目录下。   

            1)在views目录下新建一个xml文件

            2)编写以下内容

    <?xml version="1.0" encoding="utf-8"?>
    
    <odoo>
        <template id="唯一id" inherit_id="模块.继承的templateid">
            <xpath expr="xpath定位语句">
                //引入的内容,一般是link标签和script标签,把static/src目录下的css、js子目录的文件引入
            </xpath>
        </template>
    </odoo>

              3)在manifest文件中配置data,把文件加载

    "data": [
            "views/XXX.xml",
        ],

                       

  • 相关阅读:
    C++学习9 this指针详解
    福建省第八届 Triangles
    UVA 11584 Partitioning by Palindromes
    POJ 2752 Seek the Name, Seek the Fame
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    HDU 2988 Dark roads(kruskal模板题)
    HDU 1385 Minimum Transport Cost
    HDU 2112 HDU Today
    HDU 1548 A strange lift(最短路&&bfs)
  • 原文地址:https://www.cnblogs.com/ygj0930/p/10826114.html
Copyright © 2011-2022 走看看