轉(zhuǎn)自https://www.bilibili.com/read/cv12444903/
1渣锦、Odoo模型概述
1.1 初識(shí)Model
odoo中的Model分為三類
models.AbstractModel
抽象模塊: 類似于抽象類之剧,常用于繼承
models.Model
基礎(chǔ)模塊: 會(huì)根據(jù)字段和模型名在后臺(tái)數(shù)據(jù)庫(kù)生成對(duì)應(yīng)的數(shù)據(jù)表文件 常用此類Model
models.TransientModel
臨時(shí)模塊: 會(huì)在后臺(tái)生成對(duì)應(yīng)的表,根據(jù)系統(tǒng)設(shè)置的清除頻率忽洛,定時(shí)清除數(shù)據(jù),常用來作為向?qū)Ш痛鎯?chǔ)臨時(shí)數(shù)據(jù)
三者的繼承關(guān)系如下圖
1.2 模型與數(shù)據(jù)庫(kù)對(duì)應(yīng)關(guān)系
Odoo中的不同字段類型,豐富了其所在模型的信息腾夯。在定義的模型中,出現(xiàn)了何種類型的字段蔬充,就表示當(dāng)前模型可以存儲(chǔ)什么類型的信息蝶俱。在這里我們可以理解為,模型就是由各種類型的字段組合出來的饥漫,也就是字段裝飾了模型榨呆。
那odoo中定義的模型以及字段和數(shù)據(jù)庫(kù)有什么關(guān)聯(lián)呢?其實(shí)在Odoo中有一個(gè)關(guān)鍵組件---ORM層庸队,是用來進(jìn)行對(duì)象-關(guān)系映射的愕提。因此在我們創(chuàng)建一個(gè)模型后,模型就會(huì)映射成數(shù)據(jù)庫(kù)中的表皿哨,而模型中的字段,會(huì)映射成表中的列纽谒。
在Odoo中 每個(gè)模型(Model)一般是由字段+函數(shù)組成
但是证膨,這里的字段可不是python語法中的基本數(shù)據(jù)類型,而是繼承odoo.fields.Field的封裝類鼓黔。
因此央勒,這里要注意,為模型中的字段賦值時(shí)澳化,和python中的基本數(shù)據(jù)類型賦值不同崔步。odoo字段需要去調(diào)用odoo.fields.Field中的create方法或write方法進(jìn)行賦值。
這個(gè)時(shí)候缎谷,我們就會(huì)有一個(gè)疑問井濒。模型和數(shù)據(jù)庫(kù)怎么使用ORM層進(jìn)行交互的呢?
這里我們以下面的流程圖來回答這個(gè)疑問
我們可以看到列林,實(shí)際上在我們修改一條數(shù)據(jù)的時(shí)候瑞你。odoo框架與此同時(shí)幫我們生成并執(zhí)行了一條SQL語句,以此來達(dá)到了模型字段數(shù)據(jù)與數(shù)據(jù)庫(kù)進(jìn)行交互的作用希痴。
新建一條數(shù)據(jù)是執(zhí)行的create方法者甲。與上述流程圖大多一致。
這里還要注意一點(diǎn)砌创,_name是模型中最重要的屬性虏缸。此屬性會(huì)映射成對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名鲫懒,在模型中是不能缺少的。
下面就是一個(gè)模型最簡(jiǎn)的完整定義:
from odoo import models
class TestModel(models.Model):
_name = 'Test.model'
2刽辙、常規(guī)字段
2.1 基礎(chǔ)字段類型
Char: 字符型窥岩,(基本字符串字段,可以限制長(zhǎng)度扫倡,通常在客戶端顯示為單行字符串)
name = fields.Char(string='字符型')
Text: 文本型谦秧, (沒有長(zhǎng)度限制 再客戶端中顯示為文本框 可以填寫多行字符串)
notes = fields.Text(string='文本型')
Boolean: 布爾型 (包含True,和False兩個(gè)值)
flag = fields.Boolean(string='布爾型')
Integer: 整型 (封裝一個(gè)int)
nums = fields.Integer(string='整型)
Float: 浮點(diǎn)型 (digits屬性定義整數(shù)部分和小數(shù)部分的位數(shù))
money = fields.Float(string=‘浮點(diǎn)型)
rate = fields.Float(string=’概率計(jì)算‘,digits=(12,6))
2.2 高級(jí)字段類型
Date 日期類型 (包含有年月日)
now = fields.Date(string='日期型')
Datetime: 時(shí)間戳型 (包含有年月日 時(shí)分秒)
time = fields.Datetime(string='時(shí)間戳')
Html:富文本類型 (封裝一個(gè)html代碼內(nèi)容)
page = fields.Html(string='富文本類型')
Binary: 二進(jìn)制型 (封裝二進(jìn)制內(nèi)容(比如文件、圖像撵溃、音頻視頻))
any = fields.Binary(string='二進(jìn)制型")
Selection 枚舉類型 (Selection字段類型一般作為下拉列表顯示 使用的時(shí)候需要在其中預(yù)定義展示數(shù)據(jù))
gender = fields.Selection([("1", "男性"), ("2", "女性")])
reference 引用型 格式如下
其中selection是返回元組列表的函數(shù)或者是表示該字段引用哪個(gè)對(duì)象的元組列表疚鲤,reference字段在數(shù)據(jù)庫(kù)表中的存儲(chǔ)形式是(對(duì)象名,ID)
fields.reference(字段名, selection, size, ... )
上例表示 字段ref可以引用哪些對(duì)象類型的resource缘挑,可引用的對(duì)象類型從下拉框選擇集歇。下拉框的選項(xiàng)由函數(shù)links_get返回
2.3 關(guān)系字段類型
在關(guān)系字段類型中,包含有多對(duì)一 一對(duì)多 和多對(duì)多三種類型语淘,其中 一對(duì)多和多對(duì)一是一對(duì)字段诲宇,經(jīng)常一起使用。 為了更好的理解關(guān)系字段 我首先以數(shù)據(jù)庫(kù)中的表舉例惶翻,這里使用學(xué)生表 和 教室表為例姑蓝。
2.3.1 many2one 和 one2many
可以看到 多個(gè)學(xué)生對(duì)應(yīng)一個(gè)教室 是多對(duì)一的關(guān)系 一個(gè)教室對(duì)應(yīng)多個(gè)學(xué)生 是一對(duì)多的關(guān)系 并且學(xué)生表中含有一個(gè)class_id的外鍵
那么在odoo中使用多對(duì)一字段時(shí),需要在字段屬性中填寫關(guān)聯(lián)模型名稱吕粗,返回的值就是外鍵纺荧。對(duì)應(yīng)的就是關(guān)聯(lián)模型的主鍵。 當(dāng)使用一對(duì)多字段時(shí)颅筋,需要在字段屬性中填寫宙暇,關(guān)聯(lián)模型名稱,關(guān)聯(lián)字段(也就是外鍵)议泵。
這樣 多對(duì)一 和 一對(duì)多關(guān)系就建立起來了
這里需要注意一點(diǎn) 在使用many2one字段的時(shí)候占贫,可以不用同時(shí)使用one2many字段枫弟。 但是在使用one2many字段的時(shí)候洪添,many2one字段必須同時(shí)使用捐晶。
2.3.2 many2many
同樣的寺谤,多對(duì)多關(guān)系插爹。一個(gè)學(xué)生對(duì)應(yīng)多門課程捷枯,一門課程也可以對(duì)應(yīng)多個(gè)學(xué)生旋膳,是多對(duì)多的關(guān)系菌瘫。 此時(shí)就需要指定一張中間表收夸,來存儲(chǔ)兩張關(guān)聯(lián)表的主鍵字段坑匠。
在odoo中使用many2many這個(gè)字段時(shí),需要指定卧惜,關(guān)聯(lián)模型名稱厘灼、中間表名稱夹纫、當(dāng)前的關(guān)聯(lián)模型ID、需要關(guān)聯(lián)模型的ID设凹。
這里要注意舰讹,當(dāng)使用many2many這個(gè)字段時(shí)。如果沒有指定關(guān)聯(lián)表 Odoo就會(huì)自動(dòng)創(chuàng)建一張關(guān)聯(lián)表闪朱,此關(guān)聯(lián)表中包含兩張表的主鍵字段月匣。
假設(shè)我們?cè)趯W(xué)生模型中定義與課程模型多對(duì)多的關(guān)系字段 寫法如下圖所示
第一個(gè)屬性就是課程模型名稱、第二個(gè)屬性就是中間表名稱奋姿、第三個(gè)屬性就是學(xué)生id锄开、第四個(gè)屬性就是課程id。
3称诗、自動(dòng)字段和保留字段
3.1 自動(dòng)字段
什么是自動(dòng)字段呢萍悴,在我們初始創(chuàng)建模型的時(shí)候,即使你沒有在模型中創(chuàng)建以下幾個(gè)字段寓免。映射出的表中 也會(huì)出現(xiàn)對(duì)應(yīng)的列癣诱。這是由odoo系統(tǒng)管理創(chuàng)建的。
這幾個(gè)字段是:ID create_date create_uid write_date write_uid
3.2 保留字段
還要注意 在odoo中袜香,有幾個(gè)字段比較特殊撕予。是odoo預(yù)定義的保留字段。比如說 active 和 name
active字段管理記錄的顯示和隱藏蜈首,如果你創(chuàng)建了這個(gè)字段实抡,又恰好為其增加了屬性default=Fasle ,那么你創(chuàng)建的所有記錄都將看不到疾就,除非你將default=False 過濾出來。
name 顯示各種行為艺蝴。如果沒有猬腰,也不會(huì)影響系統(tǒng)的運(yùn)行,它只是會(huì)在你打開一條記錄后猜敢,無法顯示你當(dāng)前的記錄是什么姑荷。
4、常用字段屬性
接下來缩擂,我將會(huì)介紹常用字段的屬性鼠冕。在第一小節(jié)中,我們提到胯盯,是字段裝飾了模型懈费。那么同樣的,對(duì)于字段來說博脑,字段也可以由屬性進(jìn)行裝飾憎乙,通過配置屬性作為參數(shù)傳遞票罐,對(duì)字段進(jìn)行配置。
4.1 odoo字段共同屬性
通過之前的舉例觀察泞边,我們可以看到该押,有些字段雖然不是同種類型,但他們有相同的屬性阵谚。比如 string 這個(gè)字段屬性蚕礼,像string一樣可以拿去修飾不同字段的屬性,我們稱為共同屬性梢什。
在odoo中奠蹬,常用的odoo共同屬性有: string required readonly help index
4.2 odoo字段特有屬性
那么除了上述的共同屬性,還有一些各個(gè)字段的所擁有的常用屬性绳矩。
size 長(zhǎng)度屬性罩润,在odoo中,可以設(shè)置該字段的長(zhǎng)度翼馆。這個(gè)時(shí)候就可以使用字段中的size屬性割以。
nums = fields.Integer(string='整型', size=20)
default 默認(rèn)值屬性,在odoo中应媚,我們可以為簡(jiǎn)單字段严沥,添加默認(rèn)值屬性,以保證在創(chuàng)建一條記錄時(shí)中姜,這個(gè)字段有一個(gè)默認(rèn)值消玄。
flag = fields.Boolean(string='布爾型', default=True)
store屬性可以定義該字段 是否存入數(shù)據(jù)庫(kù)中 如果為False 那么此字段將不會(huì)存入數(shù)據(jù)庫(kù)中
any = fields.Binary(string='二進(jìn)制型', store=False)
在odoo中,除了使用default屬性為字段設(shè)置值丢胚,可以通過一個(gè)函數(shù)計(jì)算出來翩瓜。調(diào)用這個(gè)函數(shù)的屬性就是compute 屬性。如下圖所示 我們預(yù)先定義一個(gè)計(jì)算函數(shù)携龟,監(jiān)聽number字段兔跌。當(dāng)number字段賦值的同時(shí),money字段也會(huì)同時(shí)計(jì)算出一個(gè)值峡蟋,這就是compute屬性的作用坟桅。
4.3 動(dòng)態(tài)selection
一般作為下拉選項(xiàng),Selection字段的選項(xiàng)內(nèi)容是固定的蕊蝗。但是仅乓,根據(jù)一些特殊的業(yè)務(wù)需求∨钇荩可能會(huì)需要同一個(gè)Selection字段在不同的場(chǎng)景下有不同的下拉選項(xiàng)夸楣。那這種特殊的需求怎樣去實(shí)現(xiàn)呢?
這里就需要使用selection屬性,并在其中傳遞一個(gè)函數(shù)裕偿,來動(dòng)態(tài)顯示下拉選項(xiàng)洞慎。
gender = fields.Selection(string='性別', selection='_selection_filter', default='0')
@api.model
def _selection_filter(self):
res_filter = [('1','男性'),('2','女性')]
if flag = True:
res_filter = [('1','男性'),('2','女性'),('3',"其他")]
return res_filter
這樣按照上面的代碼邏輯 Selection的下拉選項(xiàng)就會(huì)隨著_selection_filter函數(shù)中的if條件進(jìn)行動(dòng)態(tài)的變化
4.4 動(dòng)態(tài)default
同樣的,根據(jù)一些特殊的業(yè)務(wù)需求嘿棘,默認(rèn)值也可能需要在不同的場(chǎng)景有不同的展示劲腿。這時(shí)候可以結(jié)合lambda表達(dá)式和對(duì)應(yīng)的函數(shù)進(jìn)行實(shí)現(xiàn)。
nums = fields.Integer(string='零售價(jià)',size=20鸟妙,default = lambda self: self._default_values)
@api.model
def _default_values(self):
default_value = 100
if flag = True:
default_value = 500
return default_value
這樣就能實(shí)現(xiàn)動(dòng)態(tài)默認(rèn)值的顯示焦人。 作者:神州數(shù)碼云基地 https://www.bilibili.com/read/cv12444903/ 出處:bilibili