第 3 章:模型与基础字段¶
在 上一章 的结尾,我们已经能够创建一个 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.
业务对象被声明为扩展了Python类的类,它们继承了 Model
,将它们整合到自动化的持久化系统中。
模型可以通过在其定义中设置属性来进行配置。最重要的属性是: _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
中(参见 here)文件夹
models
在crm/__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
字段可以分为两大类:’简单字段’,即直接存储在模型表中的原子值,和’关系字段’,它们链接同一模型或不同模型的记录。
简单字段示例为 Boolean
, Float
, Char
, Text
, Date
和 Selection
。
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
, 默认值: 字段的名称)用户界面中字段的标签(用户可见)。
required
(bool
, 默认值:False
)如果
True
,字段不能为空。它必须要么有一个默认值,要么在创建记录时始终给定一个值。help
(str
, 默认值:''
)为用户提供UI中的长形帮助工具提示。
index
(bool
, 默认值:False
)请求Odoo在该列上创建一个
数据库索引
_。
Exercise
为现有字段设置属性。
添加以下属性:
字段 |
属性 |
---|---|
名称 |
必填 |
期望价格 |
必填 |
重启服务器后,两个字段都应该是非空的。
自动字段¶
参考: 有关此主题的文档可以在 自动字段 中找到。
你可能已经注意到你的模型有一些你没有定义的字段。Odoo 在所有模型中创建了一些字段1。这些字段由系统管理,不能被写入,但如果有用或必要,它们可以被读取:
id
(Id
)模型记录的唯一标识符。
create_date
(Datetime
)记录创建日期。
create_uid
(Many2one
)创建记录的用户。
write_date
(Datetime
)记录的最后修改日期。
write_uid
(Many2one
)最后修改记录的用户。
既然我们已经创建了第一个模型,接下来让我们 添加一些安全性 吧!
- 1
可以 禁用某些字段的自动创建
- 2
编写原始的 SQL 查询是可能的,但需要谨慎,因为这将绕过所有 Odoo 的身份验证和安全机制。