Skip to content

08. 界面基础

前面的章节中已经创建了新模型并配置相应的访问权限,这一节我们将学习用户界面交互。在本章中将创建几个菜单,并通过菜单访问默认列表和表单视图。

1、数据文件(XML)

在前面安全简介的章节中,通过 CSV 文件添加了数据。当要加载的数据格式简单时,CSV 格式非常方便。当格式较为复杂时(例如,加载视图或电子邮件模板的结构),也可以使用 XML 格式。例如,帮助字段包含 HTML 标签。虽然可以通过 CSV 文件加载此类数据,但是使用 XML 文件更为便捷。

XML 文件必须与 CSV 文件放置在同一文件夹中,并在 __manifest__.py 中进行类似的定义。当模块安装或更新时,数据文件的内容也会按顺序加载,因此针对 CSV 文件的所有说明同样适用于 XML 文件。当数据与视图相关联时,要将其添加到 views 文件夹中。

在本章中,我们将通过 XML 文件加载第一个操作和菜单。操作和菜单是数据库表中的标准行记录。

注意:一般情况下 CSV 格式比 XML 格式性能更高。在 Odoo 中就是如此,加载 CSV 文件的速度比加载 XML 文件更快。

在 Odoo 中,用户界面(操作、菜单和视图)主要通过创建和组合 XML 文件中定义的记录来实现。一种常见的模式是“菜单 > 操作 > 视图”。用户通过浏览多个菜单层级来访问记录;最深层级是一个操作,该操作会触发记录列表的打开。

2、操作

当系统升级时,系统将自动加载操作,虽然用户界面中目前还看不到任何内容,但日志中应已显示该文件已加载:

shell
INFO odoodb odoo.modules.loading: loading estate/views/estate_property_views.xml

操作可以通过以下三种方式触发:

  • 点击菜单项(与特定操作相关联)
  • 点击视图中的按钮(如果这些按钮与操作相关联)
  • 作为对象的上下文操作

本章仅介绍第一种情况。第二种情况将在后续章节中介绍,而最后一种情况则是进阶主题的重点。在estate示例中,将实现一个菜单与 estate.property 模型关联起来,以便能够创建新的记录。该操作可以视为菜单与模型之间的连接。

property_model的基本操作如下:

xml
<record id="property_model_action" model="ir.actions.act_window">
    <field name="name">Test action</field>
    <field name="res_model">property_model</field>
    <field name="view_mode">list,form</field>
</record>

以上内容的说明如下:

  • id 是一个外部标识符,它可用于引用记录,无需知道其在数据库中的标识符。
  • model 的固定值为 ir.actions.act_window,窗口操作 (ir.actions.act_window)。
  • name 是操作的名称。
  • res_model 是该操作所适用的模型。
  • view_mode 指可用的视图;在此示例中,它们是列表视图和表单视图。稍后将看到还有其他视图模式。

在 Odoo 中随处可见此类示例,但这确实是一个简单操作的绝佳范例。需要注意 XML 数据文件的结构,因为在接下来的练习中会用到它。

实践一:添加操作

在相应的文件夹中创建 estate_property_views.xml 文件,并在__manifest__.py 文件中进行定义。为模型 estate.property 创建一个操作。重启服务器后,应该能在日志中看到该文件已被加载。

文件:estate/views/estate_property_views.xml 的代码如下:

xml

3、菜单

在本节结束时,应创建三个菜单,并显示默认视图:

为了简化声明菜单(ir.ui.menu)并将其与相应操作关联的复杂性,可以使用 <menuitem> 快捷方式。

property_model_action 的基本菜单如下:

xml
<menuitem id="property_model_menu_action" action="property_model_action"/>

菜单 property_model_menu_action 与操作 property_model_action 相关联,而该操作又与模型 property_model 相关联。如前所述,操作可以被视为菜单与模型之间的纽带。

然而,菜单总是遵循一定的架构,实际上菜单分为三个层次:

  • 根菜单,显示在应用切换器中 (Odoo 社区版的应用切换器是一个下拉菜单);
  • 一级菜单,显示在顶部栏中;
  • 操作菜单;

如下所示:

定义结构最简单的方法是在 XML 文件中创建它。test_model_action 的基本结构如下:

xml
<menuitem id="property_menu_root" name="Test">
    <menuitem id="property_first_level_menu" name="First Level">
        <menuitem id="property_model_menu_action" action="property_model_action"/>
    </menuitem>
</menuitem>

添加菜单

在相应的文件夹中创建 estate_menus.xml 文件,并在 __manifest__.py 文件中进行定义。数据文件按顺序加载。为 estate.property 操作创建三级菜单。

重启服务器并刷新浏览器。现在应该能看到菜单了,甚至可以创建第一条房产广告了!

4、字段、属性与视图

在本节末尾,售价应设为只读,卧室数量和可入住日期应具有默认值。此外,在复制记录时,售价和可入住日期的数值将不会被复制。

已将保留字段 activestate 添加到 estate.property 模型中。

到目前为止,仅在房地产广告中使用了通用视图,但在大多数情况下,我们需要对视图进行微调。Odoo 中可以进行许多微调,但通常首先是确保:

  • 某些字段具有默认值。
  • 某些字段为只读。
  • 复制记录时,某些字段不会被复制。

代码设计:

py
class Property(models.Model):
    _name = "estate.property"
    _description = "房地产模型"

    name = fields.Char("标题/名称", required=True, translate=True)
    date_availability = fields.Date(string="有效期", default=datetime.now())
    expected_price = fields.Float("期望价格", required=True)
    selling_price = fields.Float("实际售价", required=True, readonly=True, copy=False)
    bedrooms = fields.Integer("房间数量", default=2)
    # ... ....

一些新属性

在继续进行视图设计之前,让我们先回顾一下模型定义。可以看到某些属性(例如 required=True)会影响数据库中的表结构。而其他属性则会影响视图或提供默认值。

字段添加新属性

查找相应的属性(参见“字段”),以:

  • 将销售价格设为只读
  • 禁止复制可用日期和销售价格的数值
python
state = fields.Selection(
        string='状态',
        selection=[('new', '新建'), ('offer_received', '已收到报价'), ('offer_accepted', '报价已接受'), ('canceled', '取消'), ('sold', '已售出')],
        default='new',
        readonly=True,
)
active = fields.Boolean(default=True, string="活动")
最近更新