第11章:添加糖粉

从商业角度来看,我们的房地产模块现在变得有意义。我们创建了 specific views,添加了几个 action buttonsconstraints。然而我们的用户界面仍然有点粗糙。我们想向列表视图添加一些颜色,并使一些字段和按钮有条件地消失。例如,当财产被出售或取消时,“已出售”和“取消”按钮应该消失,因为此时不再允许更改状态。

本章涵盖了可以在视图中执行的操作的一小部分。请随时阅读参考文档以获得更完整的概述。

参考:与本章相关的文档可以在:doc:../../reference/user_interface/view_records`和:doc:../../reference/user_interface/view_architectures`中找到。

内联视图

注解

目标:在本节末尾,应将特定的属性列表添加到属性类型视图中:

内联列表视图

在房地产模块中,我们添加了房产报价列表。我们简单地添加了字段“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` and ``field_2`”。

可以找到一个示例 here

Exercise

添加内联列表视图。

  • 添加“One2many` field property_ids to the ``estate.property.type`”模型。

  • 在“estate.property.type”表单视图中添加字段,如本节的 目标 中所述。

小部件

参考:与本节相关的文档可以在:ref:`reference/js/widgets`中找到。

注解

目标:在本节末尾,应使用特定的小部件显示属性的状态:

状态栏小部件

显示四种状态:New、Offer Received、Offer Accepted 和 Sold。

每当我们向模型添加字段时,我们(几乎)永远不必担心这些字段在用户界面中的外观。例如,为“Date` field and a ``One2many`”字段提供日期选择器,并自动显示为列表。 Odoo 根据字段类型选择正确的“小部件”。

然而,在某些情况下,我们想要一个字段的特定表示,这可以通过``widget`` attribute. We already used it for the tag_ids field when we used the ``widget=”many2many_tags”``属性来完成。如果我们没有使用它,那么该字段将显示为列表。

每个字段类型都有一组小部件,可用于微调其显示。有些小部件还带有额外的选项。详细列表可在 领域 中找到。

Exercise

使用状态栏小部件。

使用“statusbar` widget in order to display the state of the ``estate.property`”,如本节的 目标 中所述。

提示:可以找到一个简单的示例 here

警告

同一字段在视图中多次出现

仅将字段添加到列表或表单视图**一次**。不支持多次添加。

列表顺序

参考:与本节相关的文档可以在:ref:`reference/orm/models`中找到。

注解

目标:在本节末尾,所有列表都应默认按确定的顺序显示。可以手动订购属性类型。

在前面的练习中,我们创建了几个列表视图。但是,我们从未指定默认情况下必须按哪种顺序列出记录。这对于许多业务案例来说是非常重要的事情。例如,在我们的房地产模块中,我们希望在列表顶部显示最高报价。

模型

Odoo 提供了多种设置默认顺序的方法。最常见的方法是直接在模型中定义``_order``属性。这样,检索到的记录将遵循确定的顺序,该顺序在所有视图中都保持一致,包括以编程方式搜索记录时。默认情况下,没有指定顺序,因此记录将以不确定的顺序检索,具体取决于 PostgreSQL。

_order 属性采用一个字符串,其中包含将用于排序的字段列表。它将转换为 SQL 中的 order_by 子句。例如:

from odoo import fields, models

class TestModel(models.Model):
    _name = "test_model"
    _description = "Test Model"
    _order = "id desc"

    description = fields.Char()

我们的记录按降序“id”排序,这意味着最高的排在前面。

Exercise

添加型号订购。

在其对应的模型中定义以下命令:

模型

命令

estate.property

降序 ID

estate.property.offer

降价价格

estate.property.tag

姓名

estate.property.type

姓名

看法

可以在型号级别订购。这样做的优点是在检索记录列表的任何地方都具有一致的顺序。但是,由于“default_order` attribute (example”,也可以直接在视图中定义特定顺序。

手动的

模型和视图排序都在对记录进行排序时提供了灵活性,但我们仍然需要涵盖一种情况:手动排序。用户可能希望根据业务逻辑对记录进行排序。例如,在我们的房地产模块中,我们希望手动对房产类型进行排序。将最常用的类型显示在列表顶部确实很有用。如果我们的房产中介主要销售房屋,那么将“House”出现在“Apartment”之前会更方便。

为此,需要一个``sequence`` field is used in combination with the handle widget. Obviously the sequence field must be the first field in the ``_order``属性。

Exercise

添加手动订购。

  • 添加以下字段:

模型

场地

类型

estate.property.type

顺序

整数

  • 使用正确的小部件将序列添加到“estate.property.type”列表视图中。

提示:您可以在此处找到示例:modelview

属性和选项

详细说明允许微调视图外观的所有可用功能是令人望而却步的。因此,我们将坚持使用最常见的。

形式

注解

目标:在本节末尾,属性表单视图将具有:

  • 按钮和字段的条件显示

  • 标签颜色

带喷洒的表单视图

在我们的房地产模块中,我们想要修改某些字段的行为。例如,我们不希望能够从表单视图创建或编辑属性类型。相反,我们希望在适当的菜单中处理这些类型。我们还想给标签指定颜色。为了添加这些行为自定义,我们可以将“options”属性添加到多个字段小部件。

Exercise

添加小部件选项。

  • 将适当的选项添加到“property_type_id”字段,以防止从属性表单视图创建和编辑属性类型。请查看 Many2one widget documentation 了解更多信息。

  • 添加以下字段:

模型

场地

类型

estate.property.tag

颜色

整数

然后将适当的选项添加到“tag_ids”字段,以在标签上添加颜色选择器。请查看 FieldMany2ManyTags widget documentation 了解更多信息。

第 5 章:最后,一些可以使用的 UI 中,我们看到保留字段用于特定行为。例如,视图中的``active`` field is used to automatically filter out inactive records. We added the state as a reserved field as well. It’s now time to use it! A state field can be used in combination with an ``invisible``属性用于有条件地显示按钮。

Exercise

添加按钮的条件显示。

使用 invisible 属性有条件地显示标题按钮,如本节的 目标 中所述(请注意状态修改时“已售出”和“取消”按钮如何变化)。

提示:请随时在 Odoo XML 文件中搜索 invisible= 来获取一些示例。

更一般地,可以创建一个字段“invisible`, readonly or required based on the value of other fields. Note that invisible can also be applied to other elements of the view such as button or group

invisiblereadonlyrequired 可以使用任何 Python 表达式作为值。该表达式给出了属性应用的条件。例如:

<form>
    <field name="description" invisible="not is_partner"/>
</form>

这意味着``description`` field is invisible when is_partner is False. It is important to note that a field used in invisible must be present in the view. If it should not be displayed to the user, we can use the ``invisible``属性隐藏它。

Exercise

使用``invisible``。

  • 当没有花园时,使花园面积和方向在“estate.property”表单视图中不可见。

  • 设置要约状态后,使“接受”和“拒绝”按钮不可见。

  • 当房产状态为“已接受报价”、“已售出”或“已取消”时,不允许添加报价。为此,请使用“readonly”属性。

警告

在视图中使用(条件)“readonly”属性对于防止数据输入错误很有用,但请记住,它不提供任何级别的安全性!服务器端没有进行任何检查,因此始终可以通过 RPC 调用在字段上写入。

列表

注解

目标:在本节末尾,属性和优惠列表视图应具有颜色装饰。此外,优惠和标签可以直接在列表中编辑,并且默认情况下会隐藏可用日期。

带有装饰和可选字段的列表视图 可编辑列表

当模型只有几个字段时,直接通过列表视图编辑记录而不需要打开表单视图会很有用。在房地产示例中,无需打开表单视图来添加报价或创建新标签。这可以通过“editable”属性来实现。

Exercise

使列表视图可编辑。

使“estate.property.offer` and ``estate.property.tag`”列表视图可编辑。

另一方面,当模型有很多字段时,可能会很容易在列表视图中添加太多字段并使其不清楚。另一种方法是添加字段,但可以选择隐藏它们。这可以通过“optional”属性来实现。

Exercise

将字段设置为可选。

使字段“date_availability` on the ``estate.property`”列表视图可选并默认隐藏。

最后,颜色代码对于在视觉上强调记录很有用。例如,在房地产模块中,我们希望以红色显示拒绝的报价,以绿色显示接受的报价。这可以通过“decoration-{$name}”属性来实现(完整列表请参见 领域):

<list decoration-success="is_partner==True">
    <field name="name"/>
</list>

包含“is_partner` is ``True`”的记录将显示为绿色。

Exercise

添加一些装饰。

在“estate.property”列表视图上:

  • 收到报价的房产是绿色的

  • 接受报价的房产是绿色且大胆的

  • 出售的房产表现平平

在“estate.property.offer”列表视图上:

  • 拒绝的优惠呈红色

  • 已接受的报价为绿色

  • 状态不应该再可见

尖端:

  • 请记住,属性中使用的**所有**字段都必须位于视图中!

  • 如果您想测试“Offer Received”和“Offer Accepted”状态的颜色,请在表单视图中添加该字段并手动更改它(我们稍后将为此实现业务逻辑)。

统计按钮

注解

目标:在本节的末尾,属性类型表单视图上将有一个统计按钮,单击该按钮时会显示与给定类型的属性相关的所有报价的列表。

统计按钮

如果您已经使用过 Odoo 中的一些功能模块,您可能已经遇到过“统计按钮”。这些按钮显示在表单视图的右上角,可以快速访问链接的文档。在我们的房地产模块中,我们希望有一个与给定房产类型相关的报价的快速链接,如本节的**目标**中所述。

在本教程的这一点上,我们已经了解了执行此操作的大部分概念。然而,没有单一的解决方案,如果您不知道从哪里开始,它仍然会令人困惑。我们将在练习中描述逐步解决方案。通过查找“oe_stat_button”在 Odoo 代码库中找到一些示例总是有用的。

以下练习可能比前面的练习稍微困难一些,因为它假设您能够自己在源代码中搜索示例。如果您遇到困难,附近可能有人可以帮助您;-)

本练习介绍了 相关领域 的概念。理解它的最简单方法是将其视为计算域的特定情况。 description 字段的定义如下:

...

partner_id = fields.Many2one("res.partner", string="Partner")
description = fields.Char(related="partner_id.name")

相当于:

...

partner_id = fields.Many2one("res.partner", string="Partner")
description = fields.Char(compute="_compute_description")

@api.depends("partner_id.name")
def _compute_description(self):
    for record in self:
        record.description = record.partner_id.name

每次更改合作伙伴名称时,都会修改描述。

Exercise

将统计按钮添加到属性类型。

  • 添加字段 property_type_id to estate.property.offer. We can define it as a related field on property_id.property_type_id 并将其设置为已存储。

由于此字段,报价在创建时将链接到房产类型。您可以将该字段添加到报价列表视图中以确保其正常工作。

  • 添加字段“offer_ids` to ``estate.property.type`”,它是上一步中定义的字段的 One2many 逆。

  • 添加字段“offer_count` to estate.property.type. It is a computed field that counts the number of offers for a given property type (use ``offer_ids`”来执行此操作)。

此时,您已掌握了了解有多少报价链接到某种房产类型所需的所有信息。如有疑问,请将 offer_ids and offer_count 直接添加到视图中。下一步是在单击统计按钮时显示列表。

  • 在“estate.property.type` pointing to the estate.property.offer action. This means you should use the ``type=”action””属性上创建一个统计按钮(如果需要复习,请返回到 :doc:`09_actions 的末尾)。

此时,单击统计按钮应显示所有报价。我们仍然需要过滤掉报价。

看起来不错吗?如果没有,别担心,next chapter 不需要统计按钮;-)