原文:Odoo 18 官方开发教程“Server framework 101”第 3 章。本文尽量保留原文结构、代码、练习与图片,仅进行中文翻译,并在文末增加“老赵解读”。
第 3 章:模型和基础字段
在 上一章 末尾,我们能够
创建一个 Odoo 模块。然而,此时它仍然是一个空壳,不允许我们
存储任何数据。在我们的房地产模块中,我们想要存储与房地产相关的信息
房产(名称、描述、价格、居住区域…)在数据库中。 Odoo 框架提供
促进数据库交互的工具。
在继续练习之前,请确保安装了 estate 模块,即
在应用程序列表中必须显示为“已安装”。
警告
不要使用可变全局变量。
单个 Odoo 实例可以在同一 python 进程中并行运行多个数据库。
每个数据库上可能安装了不同的模块,因此我们不能依赖
将根据安装的模块更新的全局变量。
对象关系映射
参考:与此主题相关的文档可以在
模型 API。
说明
目标:在本节末尾,应创建表
estate_property:```text
$ psql -d rd-demo
rd-demo=# SELECT COUNT(*) FROM estate_property;
count
0(1 row)
```
Odoo 的关键组件是 ORM 层。
该层避免了手动编写大多数 SQL
并提供可扩展性和安全服务2。
业务对象被声明为扩展的 Python 类
Model,将它们集成到自动化中
持久化系统。
模型可以通过在其属性中设置属性来配置
定义。最重要的属性是
_name,这是必需的并定义了名称
Odoo 系统中的模型。这是a的最小定义
模型:
from odoo import models
class TestModel(models.Model):
_name = "test_model"
此定义足以让 ORM 生成名为 test_model 的数据库表。由
约定所有模型都位于 models 目录中,并且每个模型都在其自己的中定义
Python 文件。
看一下 crm_recurring_plan表是如何定义的以及对应的Python是如何实现的
文件已导入:
- 模型在文件
crm/models/crm_recurring_plan.py中定义
(参见这里) - 文件
crm_recurring_plan.py导入到crm/models/__init__.py中
(参见这里) - 文件夹
models导入到crm/__init__.py中
(参见这里)
练习
定义房地产房产模型。
根据 CRM 模块中给出的示例,为 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,如中所示
的 目标.
练习
添加描述。
将
_description添加到您的模型以消除其中一个警告。
模型字段
参考:与此主题相关的文档可以在
字段 API。
字段用于定义模型可以存储的内容以及存储位置。字段是
定义为模型类中的属性:
from odoo import fields, models
class TestModel(models.Model):
_name = "test_model"
_description = "Test Model"
name = fields.Char()
name字段是一个 Char ,它将表示为 Python
unicode str 和 SQL VARCHAR。
类型
说明
目标:在本节末尾,一些基本的字段应该已添加到表中
estate_property:```text
$ psql -d rd-demord-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
```
字段有两大类:“简单”字段,它们是原子的
值直接存储在模型的表中,以及“关系”字段,它链接
记录(与模型相同或不同)。
简单的字段示例为 Boolean、Float、
Char、Text、Date
和 Selection。
练习
将基本字段添加到房地产房产表。
将以下基本字段添加到表中:
字段 类型 姓名 Char 描述 Text 邮政编码 Char 日期_可用性 Date 预期价格 Float 销售价格 Float 卧室 Integer 生活区 Integer 外墙 Integer 车库 Boolean 花园 Boolean 花园区 Integer 花园方向 Selection
garden_orientation字段必须有 4 个可能的值:“北”、“南”、“东”
和“西”。选择列表定义为元组列表,请参阅
这里
举个例子。
将字段添加到模型后,使用 -u estate重新启动服务器
$ ./odoo-bin --addons-path=addons,../enterprise/,../tutorials/ -d rd-demo -u estate
连接到 psql并检查表 estate_property的结构。你会注意到
一些额外的字段也被添加到表中。我们稍后会重新审视它们。
通用属性
说明
目标:在本节末尾,列
name和expected_price应为
表estate_property中不可为空:
console 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,默认值:False)- 如果是
True,则字段不能为空。它必须有一个默认值
值或在创建记录时始终被赋予一个值。 help(str,默认值:'')- 在 UI 中为用户提供长格式帮助工具提示。
index(bool,默认值:False)- 请求 Odoo 在列上创建 数据库索引。
练习
设置现有字段的属性。
添加以下属性:
字段 属性 姓名 必填 预期价格 必填 重新启动服务器后,两个字段都不应为空。
自动字段
参考:与该主题相关的文档可以在以下位置找到
自动字段。
您可能已经注意到您的模型有一些您从未定义过的字段。
Odoo 在所有模型中创建一些字段1。这些字段是
由系统管理,无法写入,但可以读取
有用或必要的:
id(Id)- 模型的记录的唯一标识符。
create_date(Datetime)- 记录的创建日期。
create_uid(Many2one)- 创建记录的用户。
write_date(Datetime)- 记录的最后修改日期。
write_uid(Many2one)- 最后修改记录的用户。
现在我们已经创建了第一个模型,让我们
添加一些安全性!
- 1
- 有可能 禁用某些自动创建
字段 - 2
- 编写原始 SQL 查询是可能的,但需要小心,因为这
绕过所有 Odoo 身份验证和安全机制。
老赵解读
Odoo 的核心不是“先设计数据库表”,而是“先定义业务模型”。字段声明同时影响数据库结构、ORM 行为、默认值和后续界面表达,这也是 Odoo 开发效率高的根本原因。
初学者最容易忽视命名和字段语义。模型技术名称、字段类型、必填规则和默认值一旦进入真实数据,修改成本会迅速升高,所以应当在这一阶段先把业务对象及其生命周期想清楚。