在上一章的末尾,我们创建了一个Odoo模块。然而,在这一点上,它仍然是一个空壳,不允许我们存储任何数据。在我们的房地产模块中,我们希望将与房地产相关的信息(名称、描述、价格、居住面积等)存储在数据库中。Odoo框架提供了促进数据库交互的工具。
在继续练习之前,请确保已安装estate
模块,即它必须在应用程序列表中显示为“已安装”。
对象关系映射(ORM)
参考:与此主题相关的文档可以在模型API中找到。
备注
目标:在本节结束时,应创建表estate_property
:$ psql -d rd-demo rd-demo=# SELECT COUNT(*) FROM estate_property; count ------- 0 (1 row)
Odoo的一个关键组件是ORM层。该层避免了手动编写大多数SQL,并提供了可扩展性和安全服务。
业务对象被声明为Python类扩展Model,该Python类将它们集成到自动持久性系统中。
可以通过在模型定义中设置属性来配置模型。最重要的属性是_name
,它是必需的,并定义了Odoo系统中模型的名称。以下是模型的最简定义:
from odoo import models
class TestModel(models.Model):
_name = "test.model"
这个定义足以让ORM生成一个名为test_model
的数据库表。按照惯例模型中_name
值中的.
由ORM自动转换为_
,所有模型都位于models
目录中,每个模型都在其自己的Python文件中定义。
看看crm_recurring_plan
表是如何定义的,以及相应的Python文件是如何导入的:
- 模型在文件
crm/models/crm_recurring_plan.py
中定义(见此处) - 文件
crm/models/crm_recurring_plan.py
在crm/models/__init__.py
中导入(见此处) models
文件夹crm/__init__.py
中导入(见此处)
练习
定义estate_property
模型。
根据CRM模块中给出的示例,为estate_property
表创建适当的文件和文件夹。
创建文件时,添加estation.property
模型的最小定义。
对Python文件的任何修改都需要重新启动Odoo服务器。当我们重新启动服务器时,我们将添加-d
和-u
参数:
$ ./odoo-bin --addons-path=../custom,../enterprise/,addons -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...
...
如果显示以上信息,就是没问题的。
练习
添加描述。
在模型中添加_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
有两大类字段:“简单”字段是直接存储在模型表中的原子值,“关系”字段链接(相同或不同模型的)记录。
简单字段包括布尔、浮点、字符、文本、日期和选择。
练习
将基本字段添加到estate_property
表中。
将以下基本字段添加到表中:
字段 类型 name Char description Text postcode Char date_availability Date expected_price Float selling_price Float bedrooms Integer living_area Integer facades Integer garage Boolean garden Boolean garden_area Integer garden_orientation Selection garden_orientation
字段必须有4个可能的值:‘North’, ‘South’, ‘East’ 和 ‘West’。选择列表定义为元组列表,请参见此处(L31-L34行)的示例。
将字段添加到模型中后,使用-u estate
参数重新启动服务器
$ ./odoo-bin --addons-path=../custom,../enterprise/,addons -d rd-demo -u estate
连接到psql
并检查estate_property
表的结构。会注意到,表中还添加了几个额外的字段。后面再作说明。
常见属性
备注
目标:在本节末尾,name
列和expected_price
列在estate_property
表中的Nullable
属性显示为not null
:$ psql -d rd-demo 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在列上创建数据库索引。
练习
设置现有字段的属性。
添加以下属性:
字段 属性 name required expected_price required 重新启动服务器后,这两个字段都不能为空。
自动字段
参考:与本主题相关的文档可以在自动字段中找到。
在模型中有几个字段是从未定义过的。Odoo在所有模型中创建了几个字段。这些字段由系统管理,不能写入,但如果有用或必要,可以读取这些字段:
- id (Id)
模型记录的唯一标识符(主键)。 - create_date (Datetime)
记录的创建日期。 - create_uid (Many2one)
创建记录的用户。 - write_date (Datetime)
记录的最后修改日期。 - write_uid (Many2one)
上次修改记录的用户。
现在我们已经创建了第一个模型,接下来添加一些访问权限(security)!
提示:可以禁用某些字段的自动创建
提示:编写原始SQL查询是可能的,但需要小心,因为这会绕过所有Odoo身份验证和安全机制。