第 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`` (see `here <https://github.com/odoo/odoo/blob/e80911aaead031e7523173789e946ac1fd27c7dc/addons/crm/models/crm_recurring_plan.py#L1-L9>`__中定义)
文件``crm_recurring_plan.py`` is imported in
crm/models/__init__.py(see `这里<https://github.com/odoo/odoo/blob/e80911aaead031e7523173789e946ac1fd27c7dc/addons/crm/models/__init__.py#L15>`__)文件夹``models`` is imported in
crm/__init__.py(see `此处<https://github.com/odoo/odoo/blob/e80911aaead031e7523173789e946ac1fd27c7dc/addons/crm/__init__.py#L5>`__)
Exercise
定义房地产模型。
根据 CRM 模块中给出的示例,为“estate_property”表创建适当的文件和文件夹。
创建文件时,添加“estate.property”模型的最小定义。
对 Python 文件的任何修改都需要重新启动 Odoo 服务器。当我们重新启动服务器时,我们将添加参数``-d`` and -u:
$ ./odoo-bin --addons-path=addons,../enterprise/,../tutorials/ -d rd-demo -u estate
-u estate means we want to upgrade the estate module, i.e. the ORM will apply database schema changes. In this case it creates a new table. -d rd-demo means that the upgrade should be performed on the rd-demo database. -u should always be used in combination with -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 field is a Char which will be represented as a Python unicode str and a 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
将基本字段添加到“房地产”表中。
在表中添加以下基本字段:
场地 |
类型 |
|---|---|
姓名 |
查尔 |
描述 |
文本 |
邮政编码 |
查尔 |
日期_可用性 |
日期 |
预期价格 |
漂浮 |
销售价格 |
漂浮 |
卧室 |
整数 |
生活区 |
整数 |
外墙 |
整数 |
车库 |
布尔值 |
花园 |
布尔值 |
花园区 |
整数 |
花园方向 |
选择 |
以 garden_orientation field must have 4 possible values: ‘North’, ‘South’, ‘East’ and ‘West’. The selection list is defined as a list of tuples, see ` 这里 <https://github.com/odoo/odoo/blob/b0e0035b585f976e912e97e7f95f66b525bc8e43/addons/crm/report/crm_activity_report.py#L31-L34>`__ 为例。
将字段添加到模型后,使用“-u estate”重新启动服务器
$ ./odoo-bin --addons-path=addons,../enterprise/,../tutorials/ -d rd-demo -u estate
连接到“psql` and check the structure of the table ``estate_property`”。您会注意到表中还添加了几个额外的字段。我们稍后会重新审视它们。
通用属性¶
注解
目标:在本节末尾,列``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,默认:字段名称)UI 中字段的标签(用户可见)。
required(bool, default:False)如果为“
True”,则该字段不能为空。它必须具有默认值,或者在创建记录时始终为其指定一个值。help(str, default:'')在 UI 中为用户提供长格式帮助工具提示。
index(bool, default:False)请求 Odoo 在列上创建 database index。
Exercise
设置现有字段的属性。
添加以下属性:
场地 |
属性 |
|---|---|
姓名 |
必需的 |
预期价格 |
必需的 |
重新启动服务器后,这两个字段都不应为空。
自动字段¶
参考:与此主题相关的文档可以在 自动字段 中找到。
您可能已经注意到您的模型有一些您从未定义过的字段。 Odoo 在所有模型中创建一些字段1。这些字段由系统管理,无法写入,但如果有用或必要,可以读取它们:
id(Id)模型记录的唯一标识符。
create_date(Datetime)记录的创建日期。
create_uid(Many2one)创建记录的用户。
write_date(Datetime)记录的最后修改日期。
write_uid(Many2one)最后修改记录的用户。
现在我们已经创建了第一个模型,让我们:doc:add some security <04_securityintro>!