跳至内容

老赵解读Odoo 18开发教程03:模型与基础字段

2026年8月15日
老赵解读Odoo 18开发教程03:模型与基础字段

原文: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是如何实现的
文件已导入:

  1. 模型在文件 crm/models/crm_recurring_plan.py 中定义
    (参见这里
  2. 文件 crm_recurring_plan.py 导入到 crm/models/__init__.py
    (参见这里
  3. 文件夹 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-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
```

字段有两大类:“简单”字段,它们是原子的
值直接存储在模型的表中,以及“关系”字段,它链接
记录(与模型相同或不同)。

简单的字段示例为 BooleanFloat
CharTextDate
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的结构。你会注意到
一些额外的字段也被添加到表中。我们稍后会重新审视它们。

通用属性

说明

目标:在本节末尾,列 nameexpected_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)

一些属性在所有字段上都可用,以下是最常见的属性:

stringstr,默认:字段的名称)
UI中字段的标签(用户可见)。
requiredbool,默认值:False
如果是 True,则字段不能为空。它必须有一个默认值
值或在创建记录时始终被赋予一个值。
helpstr,默认值:''
在 UI 中为用户提供长格式帮助工具提示。
indexbool,默认值: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 开发效率高的根本原因。

初学者最容易忽视命名和字段语义。模型技术名称、字段类型、必填规则和默认值一旦进入真实数据,修改成本会迅速升高,所以应当在这一阶段先把业务对象及其生命周期想清楚。

老赵解读Odoo 18开发教程02:创建新应用