第 3 章:模型和基本字段

previous chapter 结束时,我们能够创建一个 Odoo 模块。然而,此时它仍然是一个空壳,不允许我们存储任何数据。在我们的房地产模块中,我们希望将与房产相关的信息(名称、描述、价格、居住面积…)存储在数据库中。 Odoo 框架提供了促进数据库交互的工具。

在继续练习之前,请确保已安装“estate”模块,即它必须在应用程序列表中显示为“已安装”。

警告

不要使用可变全局变量。

单个 Odoo 实例可以在同一 python 进程中并行运行多个数据库。每个数据库上都可能安装了不同的模块,因此我们不能依赖根据安装的模块进行更新的全局变量。

对象关系映射

参考:与此主题相关的文档可以在 型号 API 中找到。

注解

目标:在本节末尾,应创建表“estate_property”:

$ psql -d rd-demo
rd-demo=# SELECT COUNT(*) FROM estate_property;
count
-------
    0
(1 row)

Odoo 的一个关键组件是 ORM 层。该层避免了手动编写大部分 SQL 并提供可扩展性和安全服务2

业务对象被声明为扩展 Model 的 Python 类,并将它们集成到自动持久性系统中。

可以通过在定义中设置属性来配置模型。最重要的属性是 _name,它是必需的并定义 Odoo 系统中模型的名称。这是模型的最小定义:

from odoo import models

class TestModel(models.Model):
    _name = "test_model"

此定义足以让 ORM 生成名为 test_model 的数据库表。按照惯例,所有模型都位于 models 目录中,并且每个模型都在其自己的 Python 文件中定义。

看一下``crm_recurring_plan``表是如何定义的以及对应的Python文件是如何导入的:

  1. 该模型在文件``crm/models/crm_recurring_plan.py`` (see `here <https://github.com/odoo/odoo/blob/e80911aaead031e7523173789e946ac1fd27c7dc/addons/crm/models/crm_recurring_plan.py#L1-L9>`__中定义)

  2. 文件``crm_recurring_plan.py`` is imported in crm/models/__init__.py (see `这里<https://github.com/odoo/odoo/blob/e80911aaead031e7523173789e946ac1fd27c7dc/addons/crm/models/__init__.py#L15>`__)

  3. 文件夹``models`` is imported in crm/__init__.py (see `此处<https://github.com/odoo/odoo/blob/e80911aaead031e7523173789e946ac1fd27c7dc/addons/crm/__init__.py#L5>`__)

Exercise

定义房地产模型。

根据 CRM 模块中给出的示例,为“estate_property”表创建适当的文件和文件夹。

创建文件时,添加“estate.property”模型的最小定义。

对 Python 文件的任何修改都需要重新启动 Odoo 服务器。当我们重新启动服务器时,我们将添加参数``-d`` and -u

$ ./odoo-bin --addons-path=addons,../enterprise/,../tutorials/ -d rd-demo -u estate

-u estate means we want to upgrade the estate module, i.e. the ORM will apply database schema changes. In this case it creates a new table. -d rd-demo means that the upgrade should be performed on the rd-demo database. -u should always be used in combination with -d

在启动过程中,您应该看到以下警告:

...
WARNING rd-demo odoo.models: The model estate.property has no _description
...
WARNING rd-demo odoo.modules.loading: The model estate.property has no access rules, consider adding one...
...

如果是这样的话,那你就应该好好的!可以肯定的是,请仔细检查“psql”,如**目标**中所示。

Exercise

添加描述。

将“_description”添加到您的模型中以消除其中一个警告。

模型字段

参考:与此主题相关的文档可以在 领域 API 中找到。

字段用于定义模型可以存储的内容以及存储的位置。字段被定义为模型类中的属性::

from odoo import fields, models

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

    name = fields.Char()

name field is a Char which will be represented as a Python unicode str and a SQL VARCHAR

类型

注解

目标:在本节末尾,应该已将几个基本字段添加到表“estate_property”中:

$ psql -d rd-demo

rd-demo=# \d estate_property;
                                            Table "public.estate_property"
    Column       |            Type             | Collation | Nullable |                   Default
--------------------+-----------------------------+-----------+----------+---------------------------------------------
id                 | integer                     |           | not null | nextval('estate_property_id_seq'::regclass)
create_uid         | integer                     |           |          |
create_date        | timestamp without time zone |           |          |
write_uid          | integer                     |           |          |
write_date         | timestamp without time zone |           |          |
name               | character varying           |           |          |
description        | text                        |           |          |
postcode           | character varying           |           |          |
date_availability  | date                        |           |          |
expected_price     | double precision            |           |          |
selling_price      | double precision            |           |          |
bedrooms           | integer                     |           |          |
living_area        | integer                     |           |          |
facades            | integer                     |           |          |
garage             | boolean                     |           |          |
garden             | boolean                     |           |          |
garden_area        | integer                     |           |          |
garden_orientation | character varying           |           |          |
Indexes:
    "estate_property_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "estate_property_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
    "estate_property_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL

字段分为两大类:“简单”字段(直接存储在模型表中的原子值)和“关系”字段(链接记录(相同或不同模型的))。

简单字段示例包括 BooleanFloatCharTextDateSelection

Exercise

将基本字段添加到“房地产”表中。

在表中添加以下基本字段:

场地

类型

姓名

查尔

描述

文本

邮政编码

查尔

日期_可用性

日期

预期价格

漂浮

销售价格

漂浮

卧室

整数

生活区

整数

外墙

整数

车库

布尔值

花园

布尔值

花园区

整数

花园方向

选择

garden_orientation field must have 4 possible values: ‘North’, ‘South’, ‘East’ and ‘West’. The selection list is defined as a list of tuples, see ` 这里 <https://github.com/odoo/odoo/blob/b0e0035b585f976e912e97e7f95f66b525bc8e43/addons/crm/report/crm_activity_report.py#L31-L34>`__ 为例。

将字段添加到模型后,使用“-u estate”重新启动服务器

$ ./odoo-bin --addons-path=addons,../enterprise/,../tutorials/ -d rd-demo -u estate

连接到“psql` and check the structure of the table ``estate_property`”。您会注意到表中还添加了几个额外的字段。我们稍后会重新审视它们。

通用属性

注解

目标:在本节末尾,列``name`` and expected_price should be not nullable in the table estate_property

rd-demo=# \d estate_property;
                                            Table "public.estate_property"
    Column       |            Type             | Collation | Nullable |                   Default
--------------------+-----------------------------+-----------+----------+---------------------------------------------
...
name               | character varying           |           | not null |
...
expected_price     | double precision            |           | not null |
...

与模型本身非常相似,可以通过将配置属性作为参数传递来配置字段:

name = fields.Char(required=True)

有些属性适用于所有字段,以下是最常见的属性:

string (str,默认:字段名称)

UI 中字段的标签(用户可见)。

required (bool, default: False)

如果为“True”,则该字段不能为空。它必须具有默认值,或者在创建记录时始终为其指定一个值。

help (str, default: '')

在 UI 中为用户提供长格式帮助工具提示。

index (bool, default: False)

请求 Odoo 在列上创建 database index

Exercise

设置现有字段的属性。

添加以下属性:

场地

属性

姓名

必需的

预期价格

必需的

重新启动服务器后,这两个字段都不应为空。

自动字段

参考:与此主题相关的文档可以在 自动字段 中找到。

您可能已经注意到您的模型有一些您从未定义过的字段。 Odoo 在所有模型中创建一些字段1。这些字段由系统管理,无法写入,但如果有用或必要,可以读取它们:

id (Id)

模型记录的唯一标识符。

create_date (Datetime)

记录的创建日期。

create_uid (Many2one)

创建记录的用户。

write_date (Datetime)

记录的最后修改日期。

write_uid (Many2one)

最后修改记录的用户。

现在我们已经创建了第一个模型,让我们:doc:add some security <04_securityintro>

1

有可能 disable the automatic creation of some fields

2

可以编写原始 SQL 查询,但需要小心,因为这会绕过所有 Odoo 身份验证和安全机制。