模型和基本欄位 在上一章的末尾,我們創建一個odoo模塊。然而,此時它仍然是一個空殼,不允許我們存儲任何數據。在我們的房地產模塊中,我們希望將與房地產相關的信息(名稱(name)、描述(description)、價格(price)、居住面積(living area)…)存儲在資料庫中。odoo框架提 ...
模型和基本欄位
在上一章的末尾,我們創建一個odoo模塊。然而,此時它仍然是一個空殼,不允許我們存儲任何數據。在我們的房地產模塊中,我們希望將與房地產相關的信息(名稱(name)、描述(description)、價格(price)、居住面積(living area)…)存儲在資料庫中。odoo框架提供了資料庫交互的工具
開始練習前,請確保estate
模塊已被安裝,也就是說必須以installed
的狀態出現在Apps
列表中,如下
對象關係映射(Object-Relational Mapping)
參考: 和本主題關聯文檔可參考 Models API.
ORM 層是odoo的一個關鍵組件。該層避免了手動寫入大部分SQL並提供可擴展性和安全服務.
業務對象被定義為繼承於 Model
的Python類。可以通過在定義中設置屬性來配置model。最重要的屬性為 _name
,該屬性定義了model在odoo系統中的屬性。以下為model的最小化定義:
from odoo import models
class TestModel(models.Model):
_name = "test.model"
該定義足夠ORM生成一張名為test_model
的表。model _name
中的 .
會被ORM自動化轉為_
。按約定所有的model位於一個名為 models
的目錄,並且每個mode被定義為一個Python文件。
來看下 crm_recurring_plan
表是怎麼定義的,以及對應Python文件是怎麼導入的:
-
在
odoo/addons/crm/models/crm_recurring_plan.py
中定義model(源碼鏈接)# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import fields, models class RecurringPlan(models.Model): _name = "crm.recurring.plan" _description = "CRM Recurring revenue plans" _order = "sequence" name = fields.Char('Plan Name', required=True, translate=True) number_of_months = fields.Integer('# Months', required=True) active = fields.Boolean('Active', default=True) sequence = fields.Integer('Sequence', default=10) _sql_constraints = [ ('check_number_of_months', 'CHECK(number_of_months >= 0)', 'The number of month can\'t be negative.'), ]
-
在
crm/models/__init__.py
中導入crm_recurring_plan.py
(源碼鏈接)# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import res_users from . import calendar from . import crm_lead from . import crm_lost_reason from . import crm_stage from . import crm_team from . import ir_config_parameter from . import res_config_settings from . import res_partner from . import digest from . import crm_lead_scoring_frequency from . import utm from . import crm_recurring_plan
-
在
crm/__init__.py
中導入models
包 (源碼鏈接)# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import controllers from . import models from . import report from . import wizard from odoo import api, SUPERUSER_ID
練習
創建estate_property
表的最小化模型
-
在
odoo14/custom/estate/models/estate_property.py
中定義model#!/usr/bin/env python # -*- coding: utf-8 -*- from odoo import model class EstateProperty(models.Model): _name = 'estate.property'
-
estate_property.py
在odoo14/custom/estate/models/__init__.py
中導入#!/usr/bin/env python # -*- coding:utf-8 -*- from . import estate_property
-
在
estate/__init__.py
中導入models
包#!/usr/bin/env python # -*- coding:utf-8 -*- from . import models
重啟odoo服務
python odoo-bin --addons-path=custom,odoo/addons -r myodoo -w test123 -d odoo -u estate
-u estate
表示更新 estate
模塊,也就是說ORM將應用資料庫模式變更。
啟動過程中可以看到類似以下告警日誌:
...
2022-12-14 06:46:02,771 23792 WARNING odoo odoo.models: The model estate.property has no _description
2022-12-14 06:46:02,920 23792 WARNING odoo odoo.models: The model estate.property has no _description
...
2022-12-14 06:46:03,498 23792 WARNING odoo odoo.modules.loading: The model estate.property has no access rules, consider adding one...
...
...
以防萬一,可以看下到資料庫看下表是否創建成功。pgAmin查看路徑:Servers -> PostgreSQL 12 -> Databases (x) ->資料庫名 -> Schemas -> public -> Tables
模型欄位(Model Fields)
參考: 該主題相關文檔可參考 Fields API
欄位用於定義model可以存儲啥及在哪裡存儲。 Fields被定義為model類的屬性:
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
.
有兩大類領域欄位:‘簡單’欄位--直接存儲在模型表中的原子值,形如Boolean
, Float
, Char
, Text
, Date
和Selection
, ‘關係型’ 欄位--連接相同或者不同模型的記錄。
給模型表estate_property添加欄位
添加以下欄位到表中
Field | Type |
---|---|
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 |
The garden_orientation
欄位必須有4種可選值:‘North’, ‘South’, ‘East’ 和‘West’。Selection(選擇列表)定義為元組列表,查看示例
修改odoo14/custom/estate/models/estate_property.py
文件
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from odoo import models,fields
class EstateProperty(models.Model):
_name = 'estate.property'
_description = 'estate property table'
name = fields.Char(size=15)
description = fields.Text()
postcode = fields.Char(size=15)
date_availability = fields.Datetime('Availability Date')
expected_price = fields.Float('expected price', digits=(8, 2)) # 最大8位,小數占2位
selling_price = fields.Float('selling price', digits=(8, 2))
bedrooms = fields.Integer()
living_area = fields.Integer()
facades = fields.Integer()
garage = fields.Boolean('garage')
garden = fields.Boolean('garden')
garden_area = fields.Integer()
garden_orientation = fields.Selection(
string='Orientation',
selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('West','West')],
help="garden orientation"
)
重啟odoo服務
python odoo-bin --addons-path=custom,odoo/addons -r myodoo -w test123 -d odoo -u estate
資料庫中驗證
常見屬性
現在假設要求 name
和expected_price
欄位值不為null
,所以需要對其修改,如下,添加欄位屬性配置required=True
name = fields.Char(required=True)
expected_price = fields.Float('expected price', digits=(8, 2), required=True) # 最大8位,小數占2位
修改後重啟odoo服務。
有些屬性是所有欄位都擁有的,最常見的幾個屬性如下:
-
string
(str
, default: 欄位名稱)UI上顯示為欄位的label (用戶可見).
-
required
(bool
, default:False
)如果為
True
, 表示該欄位值不能為空。創建記錄時必須擁有預設值或給定的值。 -
help
(str
, default:''
)UI上為用戶提供long-form 幫助提示
-
index
(bool
, default:False
)要求odoo在該列上創建資料庫索引
自動創建的欄位(Automatic Fields)
參考: 該話題相關文檔可參考 Automatic fields.
odoo會在所有model(當然,也可以配置禁止自動創建某些欄位)中創建少數欄位。這些欄位有系統管理並且不能寫,但是可以讀取,如果必要的話:
-
id
(Id
)model記錄的唯一標識
-
create_date
(Datetime
)記錄創建日期
-
create_uid
(Many2one
)記錄創建人
-
write_date
(Datetime
)記錄最後修改時間
-
write_uid
(Many2one
)記錄最後修改人
作者:授客
微信/QQ:1033553122
全國軟體測試QQ交流群:7156436
Git地址:https://gitee.com/ishouke
友情提示:限於時間倉促,文中可能存在錯誤,歡迎指正、評論!
作者五行缺錢,如果覺得文章對您有幫助,請掃描下邊的二維碼打賞作者,金額隨意,您的支持將是我繼續創作的源動力,打賞後如有任何疑問,請聯繫我!!!
微信打賞
支付寶打賞 全國軟體測試交流QQ群