在上一章中已经看到,odoo能够为给定模型生成默认视图。实际上,默认视图对于业务应用程序来说是不可接受的。相反,我们至少应该以逻辑的方式组织各个字段。

视图是在带有操作和菜单的XML文件中定义的。它们是ir.ui.view model的实例。

在我们的estate模块中,我们需要以逻辑方式组织字段:

  • 在列表(树)视图中,我们希望显示的不仅仅是名称。
  • 在表单视图中,应该对字段进行分组。
  • 在搜索视图中,我们必须能够搜索的不仅仅是名称。具体来说,我们需要"Available"的地产筛选器和按"postcode"分组的快捷方式

List(列表)

参考: 主题关联文档可参考List.

列表视图,也叫树(tree)视图, 以表格的形式显示记录。

视图根元素为<tree>。其最基础版本仅简单的列出要在表中显示的所有字段(其中每个字段都是一列):

<tree string="Tests">
<field name="name"/>
<field name="last_seen"/>
</tree>

练习 -- 添加一个自定义列表视图

在合适的XML文件中为estate.property model定义一个列表视图。 一个简单的示例

修改odoo14/custom/estate/views/estate_property_views.xml

<?xml version="1.0"?>
<odoo>
<record id="link_estate_property_action" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">tree,form</field>
</record> <!--本小节添加的内容-->
<record id="estate_property_view_tree" model="ir.ui.view">
<field name="name">estate.property.tree</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<tree string="Tests">
<field name="name" string="Title"/>
<field name="postcode" string="Postcode"/>
<field name="bedrooms" string="Bedrooms"/>
<field name="living_area" string="Living Area"/>
<field name="expected_price" string="Expected Price"/>
<field name="selling_price" string="Selling Price"/>
<field name="date_availability" string="Avalilable Form"/>
</tree>
</field>
</record>
</odoo>

注意:暂时不要添加示例中的 editable="bottom"属性

说明:

<field name="name">自定义列表名称</field>
<field name="model">模型名称,即_name的值</field>

重启服务,浏览器验证,效果如下:

说明:如果未给<field/>添加string属性,则显示如下:

Form(表单)

参考: 主题关联文档可以查看Form.

表单用于创建和编辑单条件记录,其根元素为 <form>,由高层框架元素(groupnotebook)和交互元素 (按钮和字段):

<form string="Test">
<sheet>
<group>
<group>
<field name="name"/>
</group>
<group>
<field name="last_seen"/>
</group>
<notebook>
<page string="Description">
<field name="description"/>
</page>
</notebook>
</group>
</sheet>
</form>

可以使用常规HTML标记(如"div"和"h1")以及"class"属性(Odoo提供了一些内置类)来微调外观。

一个简单示例.

练习 -- 添加自定义表单视图

在合适的XML文件中为estate.property 定义视图

为了避免每次修改视图时都重新启动服务器,可以在启动服务器时添加--dev-xml,以便只刷新页面就可以查看视图修改,如下:

python odoo-bin --addons-path=custom,odoo/addons -r myodoo -w test123 -d odoo -u estate --dev xml

修改odoo14/custom/estate/views/estate_property_views.xml

<?xml version="1.0"?>
<odoo>
<record id="link_estate_property_action" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">tree,form</field>
</record> <record id="action_lost_leads" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">tree,form</field>
</record> <record id="estate_property_view_tree" model="ir.ui.view">
<field name="name">estate.property.tree</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<tree string="Tests">
<field name="name" string="Title"/>
<field name="postcode" string="Postcode"/>
<field name="bedrooms" string="Bedrooms"/>
<field name="living_area" string="Living Area"/>
<field name="expected_price" string="Expected Price"/>
<field name="selling_price" string="Selling Price"/>
<field name="date_availability" string="Avalilable Form"/>
</tree>
</field>
</record> <!--本小节添加的内容-->
<record id="estate_property_view_form" model="ir.ui.view">
<field name="name">estate.property.form</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<form string="estate property form">
<sheet>
<h1>
<field name="name"/>
</h1>
<group>
<group>
<field name="postcode" string="Postcode" ></field>
<field name="date_availability" string="Available From"></field>
</group>
<group>
<field name="expected_price" string="Expected Price"></field>
<field name="selling_price" string="Selling Price"></field>
</group>
</group>
<notebook>
<page string="Description">
<group>
<field name="description"></field>
<field name="bedrooms"></field>
<field name="living_area"></field>
<field name="facades"></field>
<field name="garage"></field>
<field name="garden"></field>
<field name="garden_area"></field>
<field name="garden_orientation"></field>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
</odoo>

查看效果

Search(搜索)

参考: 本主题相关文档可参考Search.

搜索视图与列表及表单视图略有不同,因为它们不显示内容。尽管它们适用于特定模型,但它们用于过滤其他视图的内容(通常是聚合视图,比如列表). 除了在使用方面的不同,他们的定义方式是一样的。

搜索视图根元素为<search>。该视图最基础的版本是列出需要快捷方式的所有字段:

<search string="Tests">
<field name="name"/>
<field name="last_seen"/>
</search>

Odoo生成的默认搜索视图提供了按name筛选的快捷方式。在自定义搜索视图中添加用户可能过滤的字段是非常常见的。

搜索视图还可以包含<filter>元素,这些元素充当预定义搜索的开关。筛选器必须具有以下属性之一:

  • domain:将给定domain添加到当前搜索
  • dontext:添加一些context到当前搜索,使用group_by按给定字段名称对结果分组。

一个简单的示例.

        <record id="view_delivery_carrier_search" model="ir.ui.view">
<field name="name">delivery.carrier.search</field>
<field name="model">delivery.carrier</field>
<field name="arch" type="xml">
<search string="Delivery Carrier">
<field name="name" string="Carrier" />
<field name="delivery_type"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group expand="1" string="Group By">
<filter string="Provider" name="provider" context="{'group_by':'delivery_type', 'residual_visible':True}"/>
</group>
</search>
</field>
</record>

在进一步练习之前,有必要介绍一下domain概念。

domain

引用: 本主题相关文档可参考 Search domains.

在odoo中,domain对记录上的条件进行编码:domain是用于选择模型记录子集的条件列表。每个条件都是一个包含字段名运算符的三元组。如果指定字段满足作用于值的运算符的条件,则记录满足条件。

例如,当在Product模型上使用时,以下domain选择单价高于1000的所有services

[('product_type', '=', 'service'), ('unit_price', '>', 1000)]

默认情况下,条件与隐式AND组合在一起,这意味着记录匹配一个domain,需要满足domain中的每个条件。逻辑运算符&(AND)、|(OR)和!(NOT)可用于显式组合条件。它们用于前缀位置(运算符插入在其参数之前,而不是插入在参数之间)。例如,选择类型为“服务“或“单价”不介于1000和2000之间的产品

['|',
('product_type', '=', 'service'),
'!', '&',
('unit_price', '>=', 1000),
('unit_price', '<', 2000)]

选择类型为“服务“且“单价”介于1000和2000之间的产品

['&',('product_type', '=', 'service'),'&',('unit_price', '>=', 1000),('unit_price', '<', 2000)]

等价于

[('product_type', '=', 'service'),('unit_price', '>=', 1000),('unit_price', '<', 2000)]

选择类型为“服务“或者“单价”大于等于1000或者单价小于500的产品

['|', '|', ('product_type', '=', 'service'),('unit_price', '>=', 1000),('unit_price', '<', 500)]

选择名字为 ABC 而且语言编码不为 en_US 而且国家的编码为 be 或者 de

[('name','=','ABC'),
('language.code','!=','en_US'),
'|',('country_id.code','=','be'),
('country_id.code','=','de')]

简单一点的写法

[('name','=','ABC'),
('language.code','!=','en_US'),
('country_id.code','in', ['be', 'de'])]
波兰表示法简介

Odoo是使用了波兰表示法,简单来说,波兰表示法是一种操作符置于操作数前,并且不需要括号仍然能无歧义地解析表达的方法。

运算顺序

以二元运算为例,从左至右读入表达式,遇到一个操作符后跟随两个操作数时,则计算之,然后将结果作为操作数替换这个操作符和两个操作数;重复此步骤,直至所有操作符处理完毕。

举个例子:

['|','&','|',a,b,c,'&',d,e]

其中a,b,c,e,f,g 分别是不带逻辑运算符的表达式,表达式的运算顺序:

1、['|','&','|',a,b,c,'&',d,e]

2、['|','&',(a | b),c,'&',d,e]

3、['|',((a | b) & c),'&',d,e]

4、['|',((a | b) & c),(d & e)]

5、[(((a | b) | c) | (d & e))]

如果我们要做到这个效果

A and (B or C) and D and E

先从里面开始,把or提前

A and (or B C) and D and E

把里面的and提前,去掉括号

and A or B C and D E

所以最后的domain可以这样写

A, '|', B, C, D, E

当然,我们也可以把表达式写得更容易看一点,如下:

A, D, E, '|', B, C

练习

添加定义搜索视图

在合适的XML中为 estate.property 模型定义一个搜索视图

添加过滤和分组

添加以下内容到之前创建就的搜索视图

  • 一个显示avaliable地产的过滤器,也就说,state应该为 “New“ 或者“Offer Received”。
  • 按"postcode"分组的能力

修改odoo14/custom/estate/views/estate_property_views.xml

<?xml version="1.0"?>
<odoo>
<record id="link_estate_property_action" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">tree,form</field>
</record> <record id="action_lost_leads" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">tree,form</field>
</record> <record id="estate_property_view_tree" model="ir.ui.view">
<field name="name">estate.property.tree</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<tree string="Tests">
<field name="name" string="Title"/>
<field name="postcode" string="Postcode"/>
<field name="bedrooms" string="Bedrooms"/>
<field name="living_area" string="Living Area"/>
<field name="expected_price" string="Expected Price"/>
<field name="selling_price" string="Selling Price"/>
<field name="date_availability" string="Avalilable Form"/>
</tree>
</field>
</record> <record id="estate_property_view_form" model="ir.ui.view">
<field name="name">estate.property.form</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<form string="estate property form">
<sheet>
<h1>
<field name="name"/>
</h1>
<group>
<group>
<field name="postcode" string="Postcode" ></field>
<field name="date_availability" string="Available From"></field>
</group>
<group>
<field name="expected_price" string="Expected Price"></field>
<field name="selling_price" string="Selling Price"></field>
</group>
</group>
<notebook>
<page string="Description">
<group>
<field name="description"></field>
<field name="bedrooms"></field>
<field name="living_area"></field>
<field name="facades"></field>
<field name="garage"></field>
<field name="garden"></field>
<field name="garden_area"></field>
<field name="garden_orientation"></field>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record> <!--本小节添加的内容-->
<record id="estate_property_search_view" model="ir.ui.view">
<field name="name">estate.property.search</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<search string="Estate Property">
<!-- 搜索 -->
<field name="name" string="Title" />
<field name="postcode" string="Postcode"></field>
<separator/>
<!-- 筛选 -->
<filter string="Available" name="state" domain="['|',('state', '=', 'New'),('state', '=', 'Offer Received')]"></filter>
<filter name="bedrooms" domain="[('bedrooms', '>', 3)]"></filter>
<filter name="bedrooms and selling_price" domain="[('bedrooms', '>', 2),('selling_price', '>=', 1000)]"></filter>
<!-- 分组 -->
<group expand="1" string="Group By">
<filter string="朝向" name="garden_orientation" context="{'group_by':'garden_orientation'}"/>
</group>
</search>
</field>
</record>
</odoo>

重启服务,验证效果

odoo 开发入门教程系列-基本视图的更多相关文章

  1. odoo 开发入门教程系列-继承(Inheritance)

    继承(Inheritance) Odoo的一个强大方面是它的模块化.模块专用于业务需求,但模块也可以相互交互.这对于扩展现有模块的功能非常有用.例如,在我们的房地产场景中,我们希望在常规用户视图中直接 ...

  2. odoo 开发入门教程系列-计算的字段和变更(Computed Fields And Onchanges)

    计算的字段和变更(Computed Fields And Onchanges) 模型之间的关系是任何Odoo模块的关键组成部分.它们对于任何业务案例的建模都是必要的.然而,我们可能需要给定模型中字段之 ...

  3. odoo 开发入门教程系列-安全-简介

    安全-简介 前一章中我们已经创建了第一个打算用于存储业务数据的表.在odoo这样的一个商业应用中,第一个考虑的问题就是谁(Odoo 用户(或者组用户))可以访问数据.odoo为指定用户组用户提供了一个 ...

  4. odoo 开发入门教程系列-一些用户界面

    一些用户界面 数据文件 (XML) 参考: 该主题关联文档可以查看Data Files. 上一章,我们通过CSV文件添加了数据.当需要添加数据格式简单时,用CSV格式还是很方便的,当数据格式更复杂时( ...

  5. odoo 开发入门教程系列-模型之间的关系(Relations Between Models)

    模型之间的关系(Relations Between Models) 上一章介绍了为包含基本字段的模型创建自定义视图.然而,在任何真实的业务场景中,我们都需要不止一个模型.此外,模型之间的链接是必要的. ...

  6. odoo 开发入门教程系列-准备一些操作(Action)?

    准备一些操作(Action)? 到目前为止,我们主要通过声明字段和视图来构建模块.在任何真实的业务场景中,我们都希望将一些业务逻辑链接到操作按钮.在我们的房地产示例中,我们希望能够: 取消或将房产设置 ...

  7. odoo 开发入门教程系列-添加修饰

    添加修饰 我们的房地产模块现在从商业角度来看是有意义的.我们创建了特定的视图,添加了几个操作按钮和约束.然而,我们的用户界面仍然有点粗糙.我们希望为列表视图添加一些颜色,并使一些字段和按钮有条件地消失 ...

  8. odoo 开发入门教程系列-QWeb简史

    QWeb简史 到目前为止,我们的房地产模块的界面设计相当有限.构建列表视图很简单,因为只需要字段列表.表单视图也是如此:尽管使用了一些标记,如<group>或<page>,但在 ...

  9. odoo 开发入门教程系列-模型和基本字段

    模型和基本字段 在上一章的末尾,我们创建一个odoo模块.然而,此时它仍然是一个空壳,不允许我们存储任何数据.在我们的房地产模块中,我们希望将与房地产相关的信息(名称(name).描述(descrip ...

  10. odoo 开发入门教程系列-约束(Constraints)

    约束(Constraints) 上一章介绍了向模型中添加一些业务逻辑的能力.我们现在可以将按钮链接到业务代码,但如何防止用户输入错误的数据?例如,在我们的房地产模块中,没有什么可以阻止用户设置负预期价 ...

随机推荐

  1. C# winfrom 局域网版多人成语接龙(二)

    功能基本上是完成了,要两个人完才好玩,目前 倒计时,每组游戏玩家数量这些控制变量,都是写死再代码里的,等以后想改的时候再改,这个项目核心的功能算是实现了,但还可以扩展,比如记录一下用户的游戏数据,答对 ...

  2. WPF 不透明蒙板概述

    本文内容 先决条件 使用不透明蒙板创建视觉效果 创建不透明蒙板 将渐变用作不透明蒙板 显示另外 4 个 不透明蒙板能够使部分元素或视觉对象透明或部分透明. 要创建不透明蒙版,请将 Brush 应用于元 ...

  3. nginx学习记录【一】在windows上的安装nginx的教程

    1.下载地址 http://nginx.org/en/download.html 2.选择windows版本 如下图: 3.解压并运行 解压到指定目录,如下图 打开cmd,然后cd到那个目录,如下图: ...

  4. 如何在Windows上一键部署PaddleOCR的WebAPI服务

    PaddleOCR旨在打造一套丰富.领先.且实用的OCR工具库,助力开发者训练出更好的模型,并应用落地. 官方​开源项目地址:PaddlePaddle/PaddleOCR: Awesome multi ...

  5. 001. git基础

    目录 1. 持续集成教程 1.1 持续集成的基础概念 1.2 持续集成的一般流程 1.3 认识DevOps 1.3.1 DevOps是啥? 1.3.2 为什么需要DevOps呢? 1.3.3 DevO ...

  6. react this指向问题

    在JSX事件函数方法中的 this,默认不会绑定 this指向.如果你忘记绑定,当你调用这个函数的时候 this 的值为 undefined.所以使用时一定要绑定好this的指向. 构造方法中绑定 c ...

  7. ZeroPadding 参照

    加密时要处理. 解密时,不需要额外处理,直接NoPadding. import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; impor ...

  8. 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?

    Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的.而 Mybatis 在查询关联对象或关联集合 ...

  9. 1003 我要通过! PTA Basic Level

    我的个人博客 azoux's blog 题目 我要通过! (20 分) "答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 ...

  10. netcore 打包dll发布到nuget服务器

    可参考微软官网:NuGet.org 概述 | Microsoft Docs 一.创建类库 首先创建一个类库,就是你想要发布到nuget的类库,生成项目 二.下载并注册nuget nuget地址:htt ...