odoo 视图函数 在整个项目文件中,结构并不是十分明显,虽然它也遵循MVC设计,类比django的MTV模式,各个模块区分的十分明显,在Odoo中,视图的概念不是特别明显,很多时候,我们会将调用模型的函数直接写在models里边(即:类中)。

而对于模版Tempelate部分,odoo里边反而称做“views”,如下是odoo典型模块,销售模块sale的代码结构:

可以看到odoo的前端显示部分,对应的就是views,它是基于xml来实现的,而不是我们日常的html;

今天要说的xpath语法,就是针对于xml文件的一种语法格式。

通过xpath语法,可以对xml文件中要显示的内容,进行自定义的显示,比如:我们要插入一个新的标签在当前已经存在的标签的后边,前边,里边甚至替换。。。

这种语法看着还有点像JS的寻找父子节点。。。

1. xpath有一个用法,就是当你要修改的多个标签是在同一个目录节点下的时候,多个xpath标签可以写在同一个<record>标签中,而不用每次都去声明定义一遍,

支持的视图类型:form、tree、search ...

支持的定位方法:       


<notebook position="inside">
      <xpath expr="//page[@name='page_history']" position="inside"> <field name="mobile" position="after"> <filter name="consumable" position="after"> <group name="bank" position="after"> <xpath expr="//field[@name='standard_price']" position="replace"> <xpath expr="//button[@name='open_ui']" position="replace"> <xpath expr="//div[@class='oe_employee_details']/h4/a" position="after"> <xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/tree/field[@name='analytic_account_id']" position="replace"> <xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='analytic_account_id']" position="replace">

支持的规则:before、after、replace、inside、attributes

插入:

position='before'
position="after"


      <field name="mobile" position="after">
       <field name="sale_order_count"/>
      </field> <filter name="consumable" position="after">
<separator/>
<filter name="filter_to_qty_available" string="在手数量>0" icon="terp-accessories-archiver+" domain="[('qty_available', '>', 0)]"/>
<filter name="filter_to_virtual_available" string="预测数量>0" icon="terp-accessories-archiver+" domain="[('virtual_available', '>', 0)]"/>
</filter>

替换:
position="replace"


<xpath expr="//field[@name='standard_price']" position="replace">
<group name='cost_prices' colspan="2" col="4">
<field name="standard_price" nolabel="1" attrs="{'readonly':[('cost_method','=','average')]}"/>
<field name="cost_price_extra" groups="product.group_product_variant"/>
</group>
</xpath> <xpath expr="//button[@name='open_ui']" position="replace">
<button name="open_ui" type="object" string="Start Selling" attrs="{'invisible' : [('pos_state', 'not in', ('opened',))]}" class="oe_highlight" invisible="True"/>
</xpath>

内部创建:position="inside"


<xpath expr="//page[@name='page_history']" position="inside">
<group name="grp_task" string="Tasks">
<field name="task_ids" colspan="4" nolabel="1">
<tree string="Tasks" editable="bottom">
<field name="name"/>
<field name="user_id"/>
<field name="date_deadline"/>
<field name="state" invisible="1"/>
<button name="do_open" states="pending,draft,done,cancelled" string="Start Task" type="object" icon="gtk-media-play" help="For changing to open state" invisible="context.get('set_visible',False)"/>
<button name="action_close" states="draft,pending,open" string="Done" type="object" icon="terp-dialog-close" help="For changing to done state"/>
</tree>
</field>
</group>
</xpath>

修改属性:修改属性能够实现的功能,不要使用 replace
position="attributes"


<xpath expr="//field[@name='name']" position="attributes">
<attribute name="required">1</attribute>
</xpath>

示例代码:


<record id="product_normal_variant_form_view" model="ir.ui.view">
<field name="name">product.normal.variant.form</field>
<field name="model">product.product</field>
<field name="type">form</field>
<field name="inherit_id" ref="product.product_normal_form_view" />
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='name']" position="attributes">
<attribute name="required">1</attribute>
</xpath>
<xpath expr="//field[@name='standard_price']" position="replace">
<group name='cost_prices' colspan="2" col="4">
<field name="standard_price" nolabel="1" attrs="{'readonly':[('cost_method','=','average')]}"/>
<field name="cost_price_extra" groups="product.group_product_variant"/>
</group>
</xpath>
<sheet>
<group col="2" colspan="2" groups="base.group_extended" position="replace">
<group colspan="2" col="6" name="weight" groups="base.group_extended">
<field name="is_multi_variants" invisible="1"/>
<group colspan="2" col="2">
<separator string="Template Weights" colspan="2"/>
<field digits="(14, 3)" name="volume" attrs="{'readonly':[('type','=','service')]}"/>
<field digits="(14, 3)" name="weight" attrs="{'readonly':[('type','=','service')]}"/>
<field digits="(14, 3)" name="weight_net" attrs="{'readonly':[('type','=','service')]}"/>
</group>
<group colspan="2" col="2" attrs="{'invisible':[('is_multi_variants','=',False)]}">
<separator string="Variant Weights" colspan="2"/>
<field digits="(14, 3)" name="additional_volume" attrs="{'readonly':[('type','=','service')]}"/>
<field digits="(14, 3)" name="additional_weight" attrs="{'readonly':[('type','=','service')]}"/>
<field digits="(14, 3)" name="additional_weight_net" attrs="{'readonly':[('type','=','service')]}"/>
</group>
<group colspan="2" col="2" attrs="{'invisible':[('is_multi_variants','=',False)]}">
<separator string="Total Weights" colspan="2"/>
<field digits="(14, 3)" name="total_volume"/>
<field digits="(14, 3)" name="total_weight"/>
<field digits="(14, 3)" name="total_weight_net"/>
</group>
</group>
</group>
</sheet>
</data>
</field>
</record> <!-- 隐藏 open_ui 按钮 -->
<record model="ir.ui.view" id="pos_session_opening_form_view_openui">
<field name="name">pos.session.opening.form.view.openui</field>
<field name="model">pos.session.opening</field>
<field name="inherit_id" ref="point_of_sale.pos_session_opening_form_view"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='open_ui']" position="replace">
<button name="open_ui" type="object" string="Start Selling" attrs="{'invisible' : [('pos_state', 'not in', ('opened',))]}" class="oe_highlight" invisible="True"/>
</xpath>
</field>
</record> <record id="product_search_form_view_filter" model="ir.ui.view">
<field name="name">product.search.form.filter</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_search_form_view"/>
<field name="arch" type="xml">
<filter name="consumable" position="after">
<separator/>
<filter name="filter_to_qty_available" string="在手数量>0" icon="terp-accessories-archiver+" domain="[('qty_available', '>', 0)]"/>
<filter name="filter_to_virtual_available" string="预测数量>0" icon="terp-accessories-archiver+" domain="[('virtual_available', '>', 0)]"/>
</filter>
</field>
</record> <!-- Partner kanban view inherte -->
<record model="ir.ui.view" id="crm_lead_partner_kanban_view">
<field name="name">res.partner.kanban.saleorder.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="mobile" position="after">
<field name="sale_order_count"/>
</field>
<xpath expr="//div[@class='oe_kanban_partner_links']" position="inside">
<a name="%(sale.act_res_partner_2_sale_order)d" type="action" t-if="record.sale_order_count.value>0">
<t t-esc="record.sale_order_count.value"/> Sales
</a>
</xpath>
</field>
</record> <!-- Partners inherited form -->
<record id="view_task_partner_info_form" model="ir.ui.view">
<field name="name">res.partner.task.info.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='page_history']" position="attributes">
<attribute name="invisible">False</attribute>
</xpath>
<xpath expr="//page[@name='page_history']" position="inside">
<group name="grp_task" string="Tasks">
<field name="task_ids" colspan="4" nolabel="1">
<tree string="Tasks" editable="bottom">
<field name="name"/>
<field name="user_id"/>
<field name="date_deadline"/>
<field name="state" invisible="1"/>
<button name="do_open" states="pending,draft,done,cancelled" string="Start Task" type="object" icon="gtk-media-play" help="For changing to open state" invisible="context.get('set_visible',False)"/>
<button name="action_close" states="draft,pending,open" string="Done" type="object" icon="terp-dialog-close" help="For changing to done state"/>
</tree>
</field>
</group>
</xpath>
</field>
</record>

odoo 开发基础 -- 视图之xpath语法的更多相关文章

  1. odoo 开发基础 -- 视图之widget

    Odoo 中的widget many2many_tags one2many_list selection progressbar selection statusbar handle monetary ...

  2. odoo开发基础--模型之基本字段类型

    定义模型的时候,和python的其他框架类似,可以对比Django,同样是一个模型即:一个class对应生成数据库中的一张表, 只是odoo的继承机制比较复杂一点,在日常的开发中,定义模型的时候, 基 ...

  3. odoo 开发基础 -- postgresql重新启动、状态查看

    场景描述: 当遇到数据库不能正常访问的时候,我们首先想到的是,查看相关的告警日志,一般先查看系统的日志,然后查看数据库的日志,Linux平台下,postgresql的日志文件存放目录在如下路径: te ...

  4. 【实习第十天】odoo开发基础整合

    前言 发文时间是2019年7月19日.提一下学习odoo的感受,odoo目前在国内并不是很流行,且主流是在企业型软件,所以导致目前odoo在网上的文献很少,学习相对来说比其他框架吃力.以下为大家总结1 ...

  5. 【实习第一天】odoo开发基础(一)

    管理权限 在项目中,有个security文件夹,其中的ir.model.access文件后面带4个参数.分别代表着读,写,创建,删除的操作 想要开启权限需要将其参数调成为1,反之为0.倘若不调整参数, ...

  6. 【实习第二天】odoo开发基础(二)

    搜索视图 搜索试图包括过滤器(Filters),分组(Group By)以及收藏(Favorites) 其中还包括默认的搜索栏 搜索栏添加自定义方法 <!--views.xml--> &l ...

  7. odoo开发笔记 -- 视图继承扩展

    参考: http://www.jeffzhang.cn/Odoo-Notes-2/ http://blog.csdn.net/zhangfeng1133/article/details/4693517 ...

  8. Python自动化 【第七篇】:Python基础-面向对象高级语法、异常处理、Scoket开发基础

    本节内容: 1.     面向对象高级语法部分 1.1   静态方法.类方法.属性方法 1.2   类的特殊方法 1.3   反射 2.     异常处理 3.     Socket开发基础 1.   ...

  9. iOS开发——总结篇&IOS开发基础知识

    IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...

随机推荐

  1. Linux下通过管道杀死所有与tomcat相关的进程

    先将正确的命令放上来: ps -ef | grep ps -ef将系统中运行的进程展示出来 选择带有tomcat的进程后同时去除自身带有grep的进程,毕竟本身运行的这条命令是与tomcat相关的 a ...

  2. keras CNN解读

    loss是训练集损失值.  acc是训练集准确率.val_loss是测试集上的损失值,val_acc是测试集上的准确率. 用深度学习框架跑过实际问题的朋友一定有这样的感觉: 太神奇了, 它竟然能自己学 ...

  3. 富文本粘贴word文档内容图片处理

    公司做的项目要用到文本上传功能. 网上找了很久,大部分都有一些不成熟的问题,终于让我找到了一个成熟的项目. 下面就来看看: 1.打开工程: 对于文档的上传我们需要知道这个项目是否符合我们的初衷. 运行 ...

  4. 阿里云存储oss+怎么上传找文件夹

    最近公司做工程项目,实现文件夹云存储上传. 网上找了很久,发现网上很多项目都存在相似问题,最后终于找到了一个符合我要求的项目. 工程如下: 这里对项目的文件夹云存储上传进行分析,实现文件夹上传,如何进 ...

  5. 12-简单认识下margin

    margin margin:外边距的意思.表示边框到最近盒子的距离. /*表示四个方向的外边距离为20px*/ margin: 20px; /*表示盒子向下移动了30px*/ margin-top: ...

  6. inline-block 引发的间隙原因与解决方法

    这是一个常见的问题,但是一些新人没遇到过可能不会发现,现在我对这种现在进行了分析与总结 设置一些元素为块级元素时一般这么写 li{display:inline-block; *display:inli ...

  7. (拓扑)确定比赛名次 -- hdu -- 1285

    http://acm.hdu.edu.cn/showproblem.php?pid=1285 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  8. 通过domoticz restful接口更新数据 c# 控制台程序

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  9. bootstrap手风琴折叠

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  10. file新建文件及文件夹

    1.获取包名的根目录:mRootPath = getFilesDir().getParent(); // ====mRootPath===/data/data/com.yoyu.file  获取SD卡 ...