定義模塊數據?

重要

本教程是 開始 教程的擴展。請確保您已經完成了該教程,并使用您構建的 estate 模塊作為本教程中練習的基礎。如果您想從一個干凈的基礎開始,請從 technical-training-solutions 存儲庫中獲取 16.0-core 分支。

數據類型?

主數據?

主數據通常是模塊的技術或業務需求的一部分。換句話說,這些數據通常是模塊正常運行所必需的。這些數據將始終在安裝模塊時安裝。

我們之前已經接觸過技術數據,因為我們已經定義了 視圖操作 。這些是一種主數據。

除了技術數據外,還可以定義業務數據,例如國家、貨幣、計量單位,以及完整的國家本地化(法律報告、稅務定義、賬戶圖表)等等……

演示數據?

除了主數據(模塊正常工作所需的數據)外,我們還希望擁有演示目的的數據:

  • 幫助銷售代表快速制作演示文稿。

  • 為開發人員準備一組工作數據,以便測試新功能并查看這些新功能與他們可能沒有添加的數據的外觀。

  • 測試數據是否正確加載,且不會引發錯誤。

  • 快速設置大部分要在創建新數據庫時使用的功能。

如果您沒有明確表示不需要,啟動服務器時將自動加載演示數據。這可以在數據庫管理器或命令行中完成。

$ ./odoo-bin -h
Usage: odoo-bin [options]

Options:
--version             show program's version number and exit
-h, --help            show this help message and exit

Common options:
  [...]
  --without-demo=WITHOUT_DEMO
                      disable loading demo data for modules to be installed
                      (comma-separated, use "all" for all modules). Requires
                      -d and -i. Default is none
[...]

$ ./odoo-bin --addons-path=... -d db -i account --without-demo=all

數據聲明?

清單?

參考 : 有關此主題的文檔可以在“ 模塊清單 ”中找到。

數據可以以 CSV 或 XML 的形式聲明。每個包含數據的文件都必須在清單中添加才能加載。

在清單中添加新數據的鍵是 data (主數據)和 demo (演示數據)。兩個值都應該是一個字符串列表,表示聲明數據的相對路徑。

通常,演示數據位于“demo”文件夾中,視圖和操作位于“views”文件夾中,與安全相關的數據位于“security”文件夾中,其他數據位于“data”文件夾中。

如果您的工作目錄看起來像這樣:

estate
├── data
│   └── master_data.xml
├── demo
│   └── demo_data.xml
├── models
│   ├── *.py
│   └── __init__.py
├── security
│   └── ir.model.access.csv
├── views
│   └── estate_property_offer_views.xml
├── __init__.py
└── __manifest__.py

你的清單應該長這樣:

# -*- coding: utf-8 -*-

{
    "name": "Real Estate",
    "depends": [
        ...
    ],
    "data": [
        "security/ir.model.access.csv",  # CSV and XML files are loaded at the same place
        "views/estate_property_offer_views.xml",  # Views are data too
        "data/master_data.xml",  # Split the data in multiple files depending on the model
    ],
    "demo": [
        "demo/demo_data.xml",
    ]
    "application": True,
}

逗號分隔值(CSV)?

參考 : 有關此主題的文檔可以在“ CSV數據文件 ”中找到。

聲明簡單數據的最簡單方法是使用CSV格式。但是,這種格式在功能方面有限:對于長列表中的簡單模型,請使用它,但否則請使用XML。

id,field_a,field_b,related_id:id
id1,valueA1,valueB1,module.relatedid
id2,valueA2,valueB2,module.relatedid

小技巧

你的 IDE 可能有一個擴展程序,可以對 CSV 文件進行語法高亮顯示

Exercise

estate 模塊添加一些標準的房地產物業類型:住宅、商業、工業和土地。這些應該始終被安裝。

XML?

參考 : 有關此主題的文檔可以在 數據文件 中找到。

當要創建的數據更加復雜時,使用XML可能是有用的,甚至是必要的。

<odoo>
  <record id="id1" model="tutorial.example">
    <field name="field_a">valueA1</field>
    <field name="field_b">valueB1</field>
  </record>

  <record id="id2" model="tutorial.example">
    <field name="field_a">valueA2</field>
    <field name="field_b">valueB2</field>
  </record>
</odoo>

Exercise

estate 模塊創建一些演示數據。

字段

名稱

大別墅

拖車房屋

狀態

新建

已取消

描述

一座漂亮而寬敞的別墅

拖車公園里的家

郵政編碼

12345

54321

可用日期

2020年02月02日

1970年01月01日

期望價格

160萬

10萬

銷售價格

120,000

臥室數

6

1

生活區域

100

10

門面

4

4

車庫

花園

花園面積

十萬

花園方向

數據擴展?

在核心培訓中,我們在 第13章:繼承 章節中看到我們可以繼承(擴展)現有視圖。這是數據擴展的一個特殊情況:任何數據都可以在模塊中擴展。

當您在新模塊中向現有模型添加新字段時,您可能希望在依賴模塊中創建的記錄上填充這些字段。這可以通過給出要擴展的記錄的 xml_id 來完成。它不會替換它,在這種情況下,我們將為兩個記錄設置給定值的 field_c 。

<odoo>
  <record id="id1" model="tutorial.example">
    <field name="field_c">valueC1</field>
  </record>

  <record id="id2" model="tutorial.example">
    <field name="field_c">valueC2</field>
  </record>
</odoo>

ref?

可以使用“ref”鍵設置相關字段。該鍵的值是您想要鏈接的記錄的“xml_id”。請記住,“xml_id”由首次聲明數據的模塊的名稱組成,后跟一個點,后跟記錄的“id”(如果您在聲明它的模塊中,則僅使用“id”也可以)。

<odoo>
  <record id="id1" model="tutorial.example">
    <field name="related_id" ref="module.relatedid"/>
  </record>
</odoo>

Exercise

為您創建的屬性創建一些演示數據報價。

使用在“base”中定義的合作伙伴創建報價

合作伙伴

房地產

價格

有效期

藍色內飾

大別墅

10000

14

藍色內飾

大別墅

一百五十萬

14

裝飾迷

大別墅

1500001

14

Exercise

請確保您的兩個演示屬性的屬性類型均設置為住宅。

eval?

要分配給字段的值并不總是一個簡單的字符串,您可能需要計算它。它也可以用于優化相關值的插入,或者因為約束強制您批量添加相關值。請參見: 添加X2many字段 。

<odoo>
  <record id="id1" model="tutorial.example">
    <field name="year" eval="datetime.now().year+1"/>
  </record>
</odoo>

Exercise

您添加的優惠應該始終與模塊的安裝日期相關。

function?

在加載數據時,您可能還需要執行Python代碼。

<function model="tutorial.example" name="action_validate">
    <value eval="[ref('demo_invoice_1')]"/>
</function>

Exercise

使用“接受報價”按鈕驗證其中一個演示數據報價。拒絕其他報價。

添加 X2many 字段?

參考 : 有關此主題的文檔可以在 Command 中找到。

如果您需要在One2many或Many2many字段中添加相關數據,可以使用 Command 方法來實現。

<odoo>
  <record id="id1" model="tutorial.example">
    <field name="related_ids" eval="[
        Command.create({
            'name': 'My name',
        }),
        Command.create({
            'name': 'Your name',
        }),
        Command.link(ref('model.xml_id')),
    ]"/>
  </record>
</odoo>

Exercise

創建一個新的Property,但這次在與Offers相關聯的One2many字段中直接創建一些報價。

訪問數據?

警告

永遠不要在演示數據聲明之外訪問演示數據,即使在測試中也不行。

有多種方式可以訪問主/演示數據。

在Python代碼中,您可以使用 env.ref(self, xml_id, raise_if_not_found=True) 方法。它返回與您指定的 xml_id 相關聯的記錄集。

在 XML 中,您可以像這樣使用 ref

<odoo>
  <record id="id1" model="tutorial.example">
    <field name="related_id" ref="module.relatedid"/>
  </record>
</odoo>

它將調用ref方法,并將返回的記錄的id存儲在類型為 tutorial.example ,id為 id1 的記錄的 related_id 字段中。

在 CSV 中,列的標題必須以 :id/id 作為后綴。

id,parent_id:id,name
"child1","module.parent","Name1"
"child2","module.parent","Name2"
"child3","module.parent","Name3"

在SQL中,情況更加復雜,請參見: 高級部分 。

警告

用戶始終可以刪除數據。在編碼時要始終考慮到這一點,采取防御性編程。

高級?

什么是XML id??

由于我們不想在數據庫的每個SQL表中都有一個列 xml_id ,因此我們需要一種機制來存儲它。這是通過 ir.model.data 模型完成的。

它包含記錄的名稱( xml_id ),以及定義它的模塊,定義它的模型和其ID。

沒有更新?

使用 noupdate 標志創建的記錄在升級創建它們的模塊時不會被更新,但如果它們不存在,則會被創建。

注解

odoo-bin -i module 將繞過此設置并始終加載數據。但通常不應在生產數據庫上執行此操作。

<odoo noupdate="1">
  <record id="id1" model="model">
    <field name="fieldA" eval="True"/>
  </record>
</odoo>

導入為SQL?

在某些情況下,直接在SQL中進行導入是有意義的。但是,這是不鼓勵的,因為它繞過了ORM的所有功能,包括計算字段(包括元數據)和Python約束。

注解

通常使用原始 SQL 也會繞過 ACL 并增加注入風險。

參考 : Odoo中的安全性