第 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文件是如何导入的:
该模型定义在文件
crm/models/crm_recurring_plan.py
中(参见 此处 )。文件
crm_recurring_plan.py
在crm/models/__init__.py
中被导入(参见 此处 )。文件夹
models
在crm/__init__.py
中被导入(参见 此处 )。
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
进行双重检查。
Exercise
添加描述。
为您的模型添加 _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
中添加多个基本字段:
$ 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
字段分为两大类:“简单”字段,即直接存储在模型表中的原子值;以及“关系”字段,即链接记录(相同或不同模型的记录)。
简单字段的示例包括 Boolean
、 Float
、 Char
、 Text
、 Date
和 Selection
。
Exercise
向房地产属性表添加基本字段。
向表中添加以下基本字段:
字段 |
类型 |
---|---|
名称 |
字符 |
描述 |
文本 |
邮政编码(postcode) |
字符 |
可用日期(date_availability) |
日期 |
预期价格(expected_price) |
Float |
销售价格(selling_price) |
Float |
卧室数量(bedrooms) |
整数 |
生活区域面积(living_area) |
整数 |
立面数量(facades) |
整数 |
车库(garage) |
Boolean |
花园(garden) |
Boolean |
花园面积(garden_area) |
整数 |
花园朝向(garden_orientation) |
选择 |
garden_orientation
字段必须有 4 个可能的值:’北’、’南’、’东’ 和 ‘西’。选择列表定义为元组列表,请参阅 此处 的示例。
当字段被添加到模型后,使用 -u estate
重启服务器。
$ ./odoo-bin --addons-path=addons,../enterprise/,../tutorials/ -d rd-demo -u estate
连接到 psql
并检查表 estate_property
的结构。您会注意到表中还添加了一些额外的字段。我们将在稍后重新讨论它们。
通用属性¶
注解
目标:在本节结束时,表 estate_property
中的列 name
和 expected_price
应设置为不可为空:
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
,默认值:False
)如果为
True
,字段不能为空。它必须具有默认值,或者在创建记录时始终赋值。help
(str
,默认值:''
)为用户界面中的用户提供长格式的帮助提示。
index
(bool
,默认值:False
)请求 Odoo 在该列上创建一个 数据库索引 。
Exercise
为现有字段设置属性。
添加以下属性:
字段 |
属性 |
---|---|
名称 |
依赖 |
预期价格(expected_price) |
依赖 |
重启服务器后,这两个字段都应为不可为空。
自动字段¶
参考:与此主题相关的文档可在 自动字段 中找到。
您可能已经注意到您的模型中有一些从未定义的字段。Odoo会在所有模型中创建一些字段1。这些字段由系统管理,无法写入,但在需要或有用时可以读取:
id
(Id
)模型记录的唯一标识符。
create_date
(Datetime
)记录的创建日期。
create_uid
(Many2one
)创建记录的用户。
write_date
(Datetime
)记录的最后修改日期。
write_uid
(Many2one
)最后修改记录的用户。
现在我们已经创建了第一个模型,让我们来 添加一些安全性 吧!
- 1
可以 禁用某些字段的自动创建
- 2
编写原始SQL查询是可行的,但需要谨慎,因为这会绕过Odoo的所有身份验证和安全机制(authentication and security mechanisms)。