Chapter 3: Models And Basic Fields

At the end of the previous chapter, we were able to create an Odoo module. However, at this point it is still an empty shell which doesn’t allow us to store any data. In our real estate module, we want to store the information related to the properties (name, description, price, living area…) in a database. The Odoo framework provides tools to facilitate database interactions.

在继续练习之前,请确保已安装 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.

业务对象被声明为扩展了Python类的类,它们继承了 Model ,将它们整合到自动化的持久化系统中。

模型可以通过在其定义中设置属性来进行配置。最重要的属性是: _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 (参见 这里)

  2. 文件 crm_recurring_plan.py 被导入到 crm/models/__init__.py 中(参见 here

  3. 文件夹 modelscrm/__init__.py 中被导入(参见 here

Exercise

定义房地产属性模型。

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

创建文件后,为 estate.property 模型添加最小定义。

修改Python文件后需要重新启动Odoo服务器。当我们重新启动服务器时,我们将添加参数 -d-u

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

-u estate 意味着我们要升级 estate 模块,即 ORM 将应用数据库模式更改。 在这种情况下,它会创建一个新表。 -d rd-demo 意味着升级应该在 rd-demo 数据库上执行。 -u 应该始终与 -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 进行双重检查,就像 Goal 中演示的那样。

Exercise

添加描述。

在你的模型中添加一个 _description 来消除其中一个警告。

模型字段

参考: 有关此主题的文档可以在 字段 API 中找到。

字段用于定义模型可以存储什么以及它们存储在哪里。字段在模型类中定义为属性:

from odoo import fields, models

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

    name = fields.Char()

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

类型

注解

Goal: at the end of this section, several basic fields should have been added to the table 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

向房地产物业表添加基本字段。

将以下基本字段添加到表中:

字段

类型

名称

字符

描述

文本

邮政编码

字符

可用日期

日期

期望价格

浮点数

销售价格

浮点数

卧室数

整数

生活区域

整数

门面

整数

车库

布尔值

花园

布尔值

花园面积

整数

花园方向

选择

The garden_orientation field must have 4 possible values: ‘North’, ‘South’, ‘East’ and ‘West’. The selection list is defined as a list of tuples, see here for an example.

当字段添加到模型中时,请使用 -u estate 重新启动服务器

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

连接到 psql 并检查表格 estate_property 的结构。你会注意到表格中还添加了一些额外的字段。我们稍后会重新讨论它们。

常用属性

注解

Goal: at the end of this section, the columns 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, default: field’s name)

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

required (bool, default: False)

如果 True,字段不能为空。它必须要么有一个默认值,要么在创建记录时始终给定一个值。

help (str, default: '')

为用户提供UI中的长形帮助工具提示。

index (bool, default: False)

请求Odoo在该列上创建一个 数据库索引 _。

Exercise

为现有字段设置属性。

添加以下属性:

字段

属性

名称

必填

期望价格

必填

重启服务器后,两个字段都应该是非空的。

自动字段

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

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

id (Id)

模型记录的唯一标识符。

create_date (Datetime)

记录创建日期。

create_uid (Many2one)

创建记录的用户。

write_date (Datetime)

记录的最后修改日期。

write_uid (Many2one)

最后修改记录的用户。

Now that we have created our first model, let’s add some security!

1

可以 禁用某些字段的自动创建

2

编写原始的 SQL 查询是可能的,但需要谨慎,因为这将绕过所有 Odoo 的身份验证和安全机制。