第八章:模型之間的關系?
前一章節 (tutorials/getting_started/07_basicviews) 介紹了如何為包含基本字段的模型創建自定義視圖。然而,在任何實際的業務場景中,我們需要不止一個模型。此外,模型之間的鏈接是必要的??梢院苋菀椎叵胂笠粋€模型包含客戶,另一個模型包含用戶列表。您可能需要在任何現有的業務模型中引用客戶或用戶。
在我們的房地產模塊中,我們需要以下有關房產的信息:
購買該物業的客戶
售出該物業的房地產經紀人
物業類型:房屋、公寓、頂層公寓、城堡…
一個描述該物業的標簽列表:舒適,翻新…
收到的報價清單
多對一?
參考 : 有關此主題的文檔可以在 Many2one
中找到。
注解
目標 :本節結束時:
應該創建一個新的
estate.property.type
模型,并配備相應的菜單、操作和視圖。

應該在
estate.property
模型中添加三個 Many2one 字段:物業類型、買家和賣家。

在我們的房地產模塊中,我們想要定義物業類型的概念。物業類型可以是房屋或公寓等。根據物業類型對物業進行分類是標準的業務需求,特別是為了精細化過濾。
一個屬性只能有 一個 類型,但是同一種類型可以分配給 多個 屬性。這是由 many2one 概念支持的。
many2one 是一個簡單的鏈接到另一個對象。例如,為了在我們的測試模型中定義到 res.partner
的鏈接,我們可以編寫如下代碼::
partner_id = fields.Many2one("res.partner", string="Partner")
按照慣例,many2one 字段具有 _id
后綴。然后可以輕松地使用以下方式訪問合作伙伴中的數據:
print(my_test_object.partner_id.name)
另請參閱
在實踐中,many2one 可以在表單視圖中看作是一個下拉列表。
Exercise
添加房地產物業類型表。
創建
estate.property.type
模型并添加以下字段:
字段 |
類型 |
屬性 |
---|---|---|
名稱 |
字符 |
必填 |
按照本節的 **目標 ** 顯示的方式添加菜單
將字段
property_type_id
添加到您的estate.property
模型及其表單、樹和搜索視圖中
這個練習是前面章節的一個很好的復習:你需要創建一個 模型 ,設置 模型 ,添加一個 動作和菜單 ,以及 創建一個視圖 。
提示:不要忘記在 __init__.py
中導入任何新的 Python 文件,在 __manifest.py__
中添加新的數據文件或添加訪問權限 ;-)
再次重啟服務器并刷新以查看結果!
在房地產模塊中,我們仍然需要兩個缺失的信息:買家和銷售人員。買家可以是任何個人,但銷售人員必須是房地產機構的員工(即Odoo用戶).
在Odoo中,我們通常提到兩個模型:
res.partner
: 合作伙伴是一個物理或法律實體。它可以是公司、個人甚至是聯系地址。res.users
: 系統用戶。用戶可以是“內部用戶”,即他們可以訪問Odoo后端?;蛘咚麄兛梢允恰伴T戶用戶”,即他們不能訪問后端,只能訪問前端(例如在電子商務中訪問他們的以前的訂單)。
Exercise
添加買家和銷售人員。
使用上面提到的兩個常見模型向 estate.property
模型添加一個買家和一個銷售員。它們應該在表單視圖的一個新選項卡中添加,如本節的 目標 所示。
銷售員的默認值必須是當前用戶。不應復制買方。
提示:要獲取默認值,請查看下面的注釋或查看一個示例 這里。
注解
對象 self.env
提供了訪問請求參數和其他有用信息的方法:
self.env.cr
或self._cr
是數據庫 游標 對象;它用于查詢數據庫self.env.uid
或者self._uid
是當前用戶在數據庫中的IDself.env.user
是當前用戶的記錄self.env.context
或者self._context
是上下文字典self.env.ref(xml_id)
返回與 XML id 對應的記錄self.env[model_name]
返回給定模型的實例
現在讓我們來看看其他類型的鏈接。
多對多?
參考 : 有關此主題的文檔可以在 Many2many
中找到。
注解
目標 :本節結束時:
應創建一個新的
estate.property.tag
模型,并創建相應的菜單和操作。

應該將標簽添加到
estate.property
模型中:

在我們的房地產模塊中,我們想要定義物業標簽的概念。物業標簽是指,例如,一個被稱為“舒適”的物業或“翻新”的物業。
一個屬性可以有 多個 標簽,一個標簽也可以被分配給 多個 屬性。這是由 many2many 概念支持的。
many2many是雙向多關系:一側的任何記錄都可以與另一側的任意數量的記錄相關聯。例如,為了在我們的測試模型上定義與“account.tax”模型的鏈接,我們可以編寫::
tax_ids = fields.Many2many("account.tax", string="Taxes")
按照慣例,many2many 字段具有 _ids
后綴。這意味著可以向我們的測試模型添加多個稅。它的行為類似于記錄列表,這意味著訪問數據必須在循環中完成:
for tax in my_test_object.tax_ids:
print(tax.name)
記錄列表被稱為 記錄集 ,即記錄的有序集合。它支持集合的標準Python操作,如 len()
和 iter()
,以及額外的集合操作,如 recs1 | recs2
。
一對多?
參考 : 有關此主題的文檔可以在 One2many
中找到。
注解
目標 :本節結束時:
應創建一個新的
estate.property.offer
模型,并配備相應的表單和樹視圖。應該將報價添加到
estate.property
模型中:

在我們的房地產模塊中,我們想定義房產報價的概念。房產報價是潛在買家向賣家提供的金額。報價可能低于或高于預期價格。
一個房產只能應用于 一個 報價,但是同一個房產可以有 多個 報價。再次出現了 many2one ** 的概念。然而,在這種情況下,我們想要顯示給定房產的報價列表,因此我們將使用 ** one2many 的概念。
一個one2many字段是many2one字段的反向關系。例如,我們在測試模型中通過字段“partner_id”定義了與“res.partner”模型的鏈接。我們可以定義反向關系,即與我們的合作伙伴相關聯的測試模型列表:
test_ids = fields.One2many("test.model", "partner_id", string="Tests")
第一個參數稱為“comodel”,第二個參數是我們想要反轉的字段。
按照慣例,one2many字段具有 _ids
后綴。它們的行為類似于記錄列表,這意味著訪問數據必須在循環中完成:
for test in partner.test_ids:
print(test.name)
Exercise
添加房地產物業報價表。
創建
estate.property.offer
模型并添加以下字段:
字段 |
類型 |
屬性 |
值 |
---|---|---|---|
價格 |
浮點數 |
||
狀態 |
選擇 |
無復制 |
已接受,已拒絕 |
合作伙伴ID |
多對一( |
必填 |
|
屬性ID |
多對一( |
必填 |
創建一個樹視圖和一個表單視圖,包括
price
、partner_id
和status
字段。無需創建操作或菜單。將字段
offer_ids
添加到您的estate.property
模型中,并在其表單視圖中,如本節的 目標 所示。
這里有幾個重要的事情需要注意。首先,我們不需要為所有模型創建操作或菜單。有些模型只能通過另一個模型訪問。這是我們練習中的情況:一個報價總是通過一個屬性訪問。
其次,盡管 property_id
字段是必需的,但我們沒有在視圖中包含它。那么Odoo如何知道我們的報價與哪個物業相關聯呢?這就是使用Odoo框架的魔力的一部分:有時事情是隱含定義的。當我們通過one2many字段創建記錄時,相應的many2one字段會自動填充以方便使用。
還活著嗎?這一章節絕對不是最容易的。它介紹了一些新概念,同時又依賴于之前介紹的所有內容。 下一章節 會更輕松,不用擔心 ;-)