模型和基本欄位
在上一章的末尾,我們創建一個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群
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548025.html
標籤:其他
