第11章:添加装饰¶
我们的房地产模块现在从业务角度来看已经合理了。我们创建了 特定视图,添加了几个 操作按钮 和 约束。然而,我们的用户界面仍然有些粗糙。我们希望在列表视图中添加一些颜色,并使某些字段和按钮根据条件消失。例如,当房产已售出或取消时,’已售’ 和 ‘取消’ 按钮应该消失,因为此时不再允许更改状态。
本章节仅涵盖了视图中的一小部分功能。请阅读参考文档以获取更全面的概述。
参考:本章相关的文档可以在 View records 和 视图架构 中找到。
内联视图¶
注解
目标:在本节结束时,应将特定的属性列表添加到属性类型视图中:
在房地产模块中,我们为一个属性添加了一个报价列表。我们只需添加字段 offer_ids
即可:
<field name="offer_ids"/>
该字段使用了 estate.property.offer
的特定视图。在某些情况下,我们希望定义一个仅在表单视图上下文中使用的特定列表视图。例如,我们想要显示与某个属性类型相关联的属性列表。但是,为了清晰起见,我们只想显示3个字段:名称、预期价格和状态。
我们可以定义 内联 列表视图来实现此功能。内联列表视图直接在表单视图中定义。例如:
from odoo import fields, models
class TestModel(models.Model):
_name = "test_model"
_description = "Test Model"
description = fields.Char()
line_ids = fields.One2many("test_model_line", "model_id")
class TestModelLine(models.Model):
_name = "test_model_line"
_description = "Test Model Line"
model_id = fields.Many2one("test_model")
field_1 = fields.Char()
field_2 = fields.Char()
field_3 = fields.Char()
<form>
<field name="description"/>
<field name="line_ids">
<list>
<field name="field_1"/>
<field name="field_2"/>
</list>
</field>
</form>
在 test_model
的表单视图中,我们为 test_model_line
定义了一个特定的列表视图,其中包含字段 field_1
和 field_2
。
一个例子可以在 这里 找到。
Exercise
添加一个内联列表视图。
将
One2many
字段property_ids
添加到estate.property.type
模型中。在
estate.property.type
表单视图中添加字段,如本节的 目标 所示。
小部件¶
参考: 与本节相关的文档可以在 字段 中找到。
注解
目标:在本节结束时,应使用特定的小部件显示属性的状态:
展示了四种状态:新建、已收到报价、已接受报价和已售出。
每当我们向模型中添加字段时,我们(几乎)从未担心过这些字段在用户界面中会如何显示。例如,为 Date
字段提供了日期选择器,而 One2many
字段会自动显示为列表。Odoo 会根据字段类型选择正确的 widget。
然而,在某些情况下,我们希望字段有特定的表示方式,这可以通过 widget
属性实现。我们已经在使用 widget="many2many_tags"
属性时使用了它来处理 tag_ids
字段。如果我们没有使用它,那么该字段将显示为列表。
每个字段类型都有一组小部件,可以用来微调其显示。有些小部件还可以使用额外的选项。详细列表请参见: 字段 。
警告
在视图中多次使用同一字段
将字段仅添加 一次 到列表或表单视图中。多次添加不受支持。
订单列表¶
参考: 与本节相关的文档可以在 型号 中找到。
注解
目标:在本节结束时,所有列表默认应以确定性的顺序显示。属性类型可以手动排序。
在之前的练习中,我们创建了几个列表视图。然而,我们从未指定默认情况下记录的排序方式。这对于许多业务场景非常重要。例如,在我们的房地产模块中,我们希望将最高的报价显示在列表的顶部。
模型¶
Odoo 提供了几种设置默认顺序的方法。最常见的方法是直接在模型中定义 _order
属性。这样,检索到的记录将遵循确定性顺序,在所有视图中都是一致的,包括在编程搜索记录时。默认情况下,没有指定顺序,因此记录将以非确定性顺序检索,这取决于 PostgreSQL。
The _order
attribute takes a string containing a list of fields which will be used for sorting.
It will be converted to an order_by clause in SQL. For example:
from odoo import fields, models
class TestModel(models.Model):
_name = "test_model"
_description = "Test Model"
_order = "id desc"
description = fields.Char()
我们的记录按降序排列 id
,意味着最高的排在最前面。
Exercise
添加模型排序。
在相应的模型中定义以下订单:
模型 |
排序 |
---|---|
|
按 ID 降序排列 |
|
价格降序 |
|
名称 |
|
名称 |
View¶
排序可以在模型级别进行。这样做的好处是在检索记录列表时,无论在哪里都能保持一致的顺序。然而,也可以直接在视图中通过 default_order
属性定义特定的顺序(示例)。
手动¶
模型和视图排序都允许在排序记录时灵活处理,但仍有一种情况需要考虑:手动排序。用户可能希望根据业务逻辑对记录进行排序。例如,在我们的房地产模块中,我们希望手动对房地产类型进行排序。确实有用的是将最常用的类型显示在列表的顶部。如果我们的房地产代理主要销售房屋,则将“House”放在“Apartment”之前更为方便。
为此,sequence
字段与 handle
小部件结合使用。显然,sequence
字段必须是 _order
属性中的第一个字段。
Exercise
添加手动排序。
添加以下字段:
模型 |
字段 |
类型 |
---|---|---|
|
序列 |
整数 |
使用正确的小部件将序列添加到
estate.property.type
列表视图中。
提示:你可以在这里找到一个例子: model <https://github.com/odoo/odoo/blob/892dd6860733c46caf379fd36f57219082331b66/addons/crm/models/crm_stage.py#L36>
__ 和 view <https://github.com/odoo/odoo/blob/892dd6860733c46caf379fd36f57219082331b66/addons/crm/views/crm_stage_views.xml#L23>
__。
属性和选项¶
详细介绍所有可用于微调视图外观的功能将是不切实际的。因此,我们将只介绍最常见的功能。
表单¶
注解
目标:在本节结束时,属性表单视图将具备:
按钮和字段的条件显示
标签颜色
在我们的房地产模块中,我们想要修改一些字段的行为。例如,我们不希望能够从表单视图中创建或编辑属性类型。相反,我们希望在它们适当的菜单中处理这些类型。我们还想给标签添加颜色。为了添加这些行为自定义,我们可以向几个字段小部件添加 options
属性。
Exercise
添加小部件选项。
在属性表单视图中,为
property_type_id
字段添加适当的选项,以防止创建和编辑属性类型。更多信息,请参阅: Many2one widget documentation 。添加以下字段:
模型 |
字段 |
类型 |
---|---|---|
|
颜色 |
整数 |
然后在 tag_ids
字段中添加适当的选项,以在标签上添加颜色选择器。请参阅 FieldMany2ManyTags widget documentation 以获取更多信息。
在 第5章:终于,有了可以操作的UI 中,我们了解到保留字段用于特定的行为。例如,active
字段用于自动过滤掉非活动记录。我们还添加了 state
作为保留字段。现在是时候使用它了!state
字段可以与视图中的 invisible
属性结合使用,以有条件地显示按钮。
Exercise
添加按钮的条件显示。
使用 invisible
属性根据条件显示标题按钮,如本节 目标 所示(注意当状态修改时 ‘Sold’ 和 ‘Cancel’ 按钮如何变化)。
提示:不妨在 Odoo 的 XML 文件中搜索 invisible=
以获取一些示例。
更一般地,可以根据其他字段的值使字段 invisible
、readonly
或 required
。注意,invisible
也可以应用于视图中的其他元素,如 button
或 group
。
invisible
、readonly
和 required
可以接受任何 Python 表达式作为值。该表达式给出了属性适用的条件。例如:
<form>
<field name="description" invisible="not is_partner"/>
</form>
这意味着当 is_partner
为 False
时,description
字段不可见。需要注意的是,在 invisible
中使用的字段 必须 存在于视图中。如果不应向用户显示该字段,我们可以使用 invisible
属性来隐藏它。
Exercise
使用 invisible
。
当没有花园时,在
estate.property
表单视图中使花园面积和朝向不可见。一旦报价状态设置,使“接受”和“拒绝”按钮不可见。
当房产状态为 ‘Offer Accepted’、’Sold’ 或 ‘Cancelled’ 时,不允许添加报价。为此,请使用
readonly
属性。
警告
在视图中使用(条件) readonly
属性可以防止数据输入错误,但请记住它不提供任何安全级别!没有进行服务器端检查,因此始终可以通过RPC调用在字段上写入。
列表¶
注解
目标:在本节结束时,属性和报价列表视图应该具有颜色装饰。此外,报价和标签将可以直接在列表中编辑,并且可用日期将默认隐藏。
当模型只有少量字段时,直接通过列表视图编辑记录而无需打开表单视图可能会很有用。在房地产示例中,添加报价或创建新标签时无需打开表单视图。这可以通过 editable
属性实现。
Exercise
使列表视图可编辑。
使 estate.property.offer
和 estate.property.tag
的列表视图可编辑。
另一方面,当一个模型有很多字段时,很容易在列表视图中添加过多的字段,使其变得不清晰。另一种方法是添加这些字段,但是将它们设为可选隐藏。这可以通过 optional
属性来实现。
Exercise
将字段设为可选。
将 estate.property
列表视图上的字段 date_availability
设置为默认情况下可选和隐藏。
最后,颜色代码对于视觉上强调记录非常有用。例如,在房地产模块中,我们希望以红色显示被拒绝的报价,以绿色显示被接受的报价。这可以通过 decoration-{$name}
属性实现(参见: 字段 以获取完整列表):
<list decoration-success="is_partner==True">
<field name="name"/>
</list>
当 is_partner
为 True
时,记录将以绿色显示。
Exercise
添加一些装饰品。
在 estate.property
列表视图中:
已收到报价的房产标记为绿色
已接受报价的房产为绿色和粗体
已售出的物业已静音
在 estate.property.offer
列表视图中:
拒绝的报价是红色的
已接受的报价为绿色
该状态不应再可见
小费:
请记住, 所有 用于属性的字段都必须在视图中!
如果您想测试“已收到报价”和“已接受报价”状态的颜色,请在表单视图中添加该字段并手动更改它(稍后我们将实现业务逻辑)。
搜索¶
注解
目标:在本节结束时,可用的属性将默认被过滤,并且在居住面积上的搜索将返回面积大于给定数字的结果。
最后但并非最不重要的是,当我们进行搜索时,有一些微调我们想要应用。首先,我们希望在访问属性时默认应用我们的“可用”过滤器。为了实现这一点,我们需要使用 search_default_{$name}
动作上下文,其中 {$name}
是过滤器名称。这意味着我们可以在动作级别上定义默认激活的过滤器(们)。
Exercise
添加默认过滤器。
在 estate.property
操作中,默认选择“可用”过滤器。
我们模块中另一个有用的改进是能够通过居住面积高效地进行搜索。实际上,用户将希望搜索“至少”具有给定面积的属性。期望用户要找到一个精确的居住面积的属性是不现实的。虽然可以制作自定义搜索,但这很不方便。
搜索视图中的 <field>
元素可以具有 filter_domain
,该元素覆盖了为给定字段搜索生成的域。在给定的域中, self
表示用户输入的值。在下面的示例中,它用于在 name
和 description
字段上进行搜索。
<search string="Test">
<field name="description" string="Name and description"
filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>
</search>
Exercise
更改客厅搜索。
在生活区中添加一个 filter_domain
,以包括面积等于或大于给定值的属性。