ORM API?

對象關系映射模塊:
  • 分層結構

  • 約束一致性和驗證

  • 對象元數據取決于其狀態

  • 通過復雜查詢進行優化處理(一次執行多個操作)

  • 默認字段值

  • 權限優化

  • 持久化對象:DB postgresql

  • 數據轉換

  • 多級緩存系統

  • 兩種不同的繼承機制

  • 豐富的字段類型集合:
    • 傳統類型(varchar、integer、boolean等)

    • 關系型(一對多,多對一,多對多)

    • 功能性的

模型?

模型字段定義為模型本身的屬性:

from odoo import models, fields
class AModel(models.Model):
    _name = 'a.model.name'

    field1 = fields.Char()

警告

這意味著您不能定義一個與方法同名的字段,否則后者將會悄悄地覆蓋前者。

默認情況下,字段的標簽(用戶可見名稱)是字段名稱的大寫版本,可以使用“string”參數覆蓋此設置。:

field2 = fields.Integer(string="Field Label")

有關字段類型和參數的列表,請參見: 字段參考 。

默認值是作為字段參數定義的,可以是一個值:

name = fields.Char(default="a value")

或者作為一個被調用以計算默認值的函數,該函數應該返回該值:

def _default_name(self):
    return self.get_value()

name = fields.Char(default=lambda self: self._default_name())

API

class odoo.models.BaseModel[源代碼]?

Odoo模型的基類。

Odoo模型是通過繼承以下模型之一創建的:

  • Model 用于常規數據庫持久化模型

  • TransientModel 用于存儲在數據庫中的臨時數據,但會定期自動清理

  • AbstractModel 用于抽象超類,可被多個繼承模型共享

系統會自動為每個數據庫實例化每個模型一次。這些實例代表每個數據庫上可用的模型,并且取決于該數據庫上安裝的模塊。每個實例的實際類是由創建和繼承相應模型的Python類構建的。

每個模型實例都是一個“記錄集”,即該模型的記錄的有序集合。記錄集由諸如 browse() 、 search() 或字段訪問等方法返回。記錄沒有顯式的表示方式:一個記錄被表示為一個只包含一個記錄的記錄集。

要創建一個不應該被實例化的類,可以將 _register 屬性設置為 False。

_auto = False?

是否應該創建數據庫表。如果設置為 False ,請覆蓋 init() 方法來創建數據庫表。

對于 ModelTransientModel ,自動默認為 True ,對于 AbstractModel ,自動默認為 False 。

小技巧

要創建一個沒有表的模型,請繼承自 AbstractModel 。

_log_access?

ORM是否應自動生成并更新 訪問日志字段 。

默認為 _auto 設置的任何值。

_table = None?

如果 _auto 為真,則模型使用的 SQL 表名

_sql_constraints = []?

SQL 約束條件 [(名稱,SQL定義,消息)]

_register = False?

注冊表可見性

_abstract = True?

模型是否為 抽象 模型。

另請參閱

AbstractModel

_transient = False?

模型是否為 瞬態 。

另請參閱

TransientModel

_name = None?

模型名稱(點符號表示法,模塊命名空間)

_description = None?

模型的非正式名稱

_inherit = ()?

Python繼承的模型:

類型

字符串或字符串列表

注解

  • 如果設置了 _name ,則繼承的父模型名稱

  • 如果 _name 未設置,則為要就地擴展的單個模型的名稱

_inherits = {}?

字典{‘parent_model’: ‘m2o_field’}將父業務對象的_name映射到相應的外鍵字段名稱以使用:

_inherits = {
    'a.model': 'a_field_id',
    'b.model': 'b_field_id'
}

實現基于組合的繼承:新模型公開繼承模型的所有字段,但不存儲它們:值本身仍存儲在鏈接記錄上。

警告

如果在 _inherits 中繼承的模型中定義了多個同名字段,那么繼承的字段將對應于最后一個(按照繼承列表的順序)。

_rec_name = None?

用于標記記錄的字段,默認為“名稱”

_order = 'id'?

搜索結果的默認排序字段

_check_company_auto = False?

在寫入和創建時,調用 _check_company 來確保具有 check_company=True 屬性的關系字段的公司一致性。

_parent_name = 'parent_id'?

用作父級字段的many2one字段

_parent_store = False?

設置為True以計算parent_path字段。

除了 parent_path 字段外,還設置了一個索引存儲記錄的樹形結構,以便使用 child_ofparent_of 域運算符更快地進行當前模型記錄的分層查詢。

_fold_name = 'fold'?

用于確定看板視圖中折疊組的字段

抽象模型?

odoo.models.AbstractModel[源代碼]?

alias of odoo.models.BaseModel

模型?

class odoo.models.Model(env, ids, prefetch_ids)[源代碼]?

常規數據庫持久化Odoo模型的主超類。

Odoo模型是通過繼承此類創建的:

class user(Model):
    ...

系統稍后將在每個安裝了該類模塊的數據庫中實例化該類。

_auto = True?

是否應該創建數據庫表。如果設置為 False ,請覆蓋 init() 方法來創建數據庫表。

對于 ModelTransientModel ,自動默認為 True ,對于 AbstractModel ,自動默認為 False 。

小技巧

要創建一個沒有表的模型,請繼承自 AbstractModel 。

_abstract = False?

模型是否為 抽象 模型。

另請參閱

AbstractModel

瞬態模型?

class odoo.models.TransientModel(env, ids, prefetch_ids)[源代碼]?

瞬態記錄的模型超類,用于臨時持久化,并定期進行清理。

瞬態模型具有簡化的訪問權限管理,所有用戶都可以創建新記錄,并且只能訪問他們創建的記錄。超級用戶可以無限制地訪問所有瞬態模型記錄。

_transient_max_count = False?

瞬態記錄的最大數量,如果為 0 則無限制

_transient_max_hours = 1.0?

最大空閑生命周期(以小時為單位),如果為 0 則無限制

_transient_vacuum()[源代碼]?

清理瞬態記錄。

每當達到 _transient_max_count_transient_max_hours (如果有)條件時,此功能將從瞬態模型表中取消鏈接舊記錄。

實際清理只會在每5分鐘內發生一次。這意味著可以頻繁調用此方法(例如每次創建新記錄時)。

同時啟用max_hours和max_count的示例:

假設max_hours = 0.2(即12分鐘),max_count = 20,表中有55行,其中有10行在最近5分鐘內創建/更改,另外12行在5到10分鐘之間創建/更改,其余的行創建/更改時間超過12分鐘。

  • 基于時間的清理將保留最近12分鐘內創建/更改的22行記錄

  • 計數基礎的清理將會清除另外12行。不僅僅是2行,否則每次添加都會立即導致最大值再次達到。

  • 過去5分鐘內創建/更改的10行記錄將不會被刪除

字段?

class odoo.fields.Field[源代碼]?

字段描述符包含字段定義,并管理記錄上相應字段的訪問和賦值。在實例化字段時,可以提供以下屬性:

參數
  • string (str) – 用戶可見的字段標簽;如果未設置,則ORM將使用類中的字段名稱(大寫)。

  • help (str) – 用戶可見的字段工具提示

  • invisible – 字段是否不可見(布爾型,默認為 False

  • readonly (bool) – 字段是否只讀(默認值: False )。這僅影響用戶界面。任何代碼中的字段賦值都將起作用(如果字段是存儲字段或可逆字段)。

  • required (bool) – 字段的值是否必填(默認值: False

  • index (str) – 字段是否在數據庫中建立索引,以及索引的類型。注意:這不會影響非存儲和虛擬字段??赡艿闹禐椋?* "btree"True :標準索引,適用于many2one * "btree_not_null" :沒有NULL值的BTREE索引(當大多數值為NULL或從不搜索NULL時有用) * "trigram" :具有三元組的廣義反向索引(適用于全文搜索)* NoneFalse :沒有索引(默認)

  • default (value or callable) – 字段的默認值;可以是靜態值,也可以是一個接收記錄集并返回值的函數;使用 default=None 來丟棄字段的默認值。

  • states (dict) – 一個將狀態值映射到UI屬性值對列表的字典;可能的屬性有: readonly , required , invisible 。..警告:任何基于狀態的條件都需要在客戶端UI上可用的 state 字段值。這通常是通過在相關視圖中包含它來完成的,如果對最終用戶不相關,則可能會使其不可見。

  • groups (str) – 逗號分隔的組xml id列表(字符串);這將限制字段訪問僅限于給定組的用戶

  • company_dependent (bool) – 字段值是否依賴于當前公司;該值不存儲在模型表中,而是注冊為 ir.property 。當需要使用company_dependent字段的值時,會搜索與當前公司(和當前記錄,如果存在一個屬性)相關聯的 ir.property 。如果在記錄上更改了該值,則會修改當前記錄的現有屬性(如果存在一個),或為當前公司和res_id創建一個新屬性。如果在公司側更改了該值,則會影響所有未更改該值的記錄。

  • copy (bool) – 是否在復制記錄時復制字段值(默認情況下,對于普通字段為 True ,對于 one2many 和計算字段(包括屬性字段和相關字段)為 False

  • store (bool) – 字段是否存儲在數據庫中(default: True ,計算字段為 False )

  • group_operator (str) – 聚合函數用于 read_group() 在對該字段進行分組時。支持的聚合函數有: * array_agg :將值(包括空值)連接成一個數組* count :行數 * count_distinct :不同行數* bool_and :如果所有值都為真,則為真,否則為假 * bool_or :如果至少有一個值為真,則為真,否則為假* max :所有值中的最大值 * min :所有值中的最小值* avg :所有值的平均值(算術平均值)* sum :所有值的總和

  • group_expand (str) – 用于在當前字段分組時擴展read_group結果的函數。.. code-block:: python @api.model def _read_group_selection_field(self, values, domain, order): return [‘choice1’, ‘choice2’, …] # 可用的選擇項。 @api.model def _read_group_many2one_field(self, records, domain, order): return records + self.search([custom_domain])

計算字段

參數
  • compute (str) – 計算字段的方法名稱 .. 參見: 高級字段/計算字段

  • precompute (bool) – 是否在記錄插入數據庫之前計算字段。當字段可以在記錄插入之前計算時,應該手動將某些字段指定為precompute=True。(例如,避免基于搜索/讀取組的統計字段,many2one鏈接到上一個記錄等)(默認值: False ).. warning:: 僅當未提供顯式值和默認值時,預計算才會發生create()。這意味著默認值會禁用預計算,即使將字段指定為precompute=True也是如此。如果給定模型的記錄不是批量創建的,則預計算字段可能會適得其反??紤]一次創建許多記錄的情況。如果字段沒有預計算,則通常會在flush()中批量計算,并且預取機制將有助于使計算效率高。另一方面,如果字段已經預計算,則計算將逐個進行,因此將無法利用預取機制。根據上述備注,預計算字段可能在one2many的行上很有趣,這些行通常由ORM本身批量創建,前提是它們是通過寫入包含它們的記錄來創建的。

  • compute_sudo (bool) – 字段是否應該作為超級用戶重新計算以繞過訪問權限(對于存儲字段默認為 True ,對于非存儲字段默認為 False

  • recursive (bool) – 字段是否具有遞歸依賴關系(字段 X 具有類似于 parent_id.X 的依賴關系);聲明字段為遞歸必須是顯式的,以確保重新計算的正確性。

  • inverse (str) – 反轉字段的方法名稱(可選)

  • search (str) – 實現字段搜索的方法名稱(可選)

  • related (str) – 字段名稱的順序

  • default_export_compatible (bool) – 字段是否必須在兼容導入的導出中默認導出 .. 參見:: 高級字段/相關字段

基本字段?

class odoo.fields.Boolean[源代碼]?

封裝了一個 bool 。

class odoo.fields.Char[源代碼]?

基本字符串字段,可以限制長度,在客戶端通常顯示為單行字符串。

參數
  • size (int) – 該字段存儲的值的最大大小

  • trim (bool) – 指定值是否被修剪(默認為 True )。請注意,修剪操作僅在Web客戶端中應用。

  • translate (bool or callable) – 啟用字段值的翻譯;使用 translate=True 以整體方式翻譯字段值; translate 也可以是可調用對象,使得 translate(callback, value) 通過使用 callback(term) 來檢索術語的翻譯來翻譯 value 。

class odoo.fields.Float[源代碼]?

封裝了一個 float 。

精度數字由(可選的) digits 屬性給出。

參數

digits (tuple(int,int) or str) – 一對(總數,小數)或一個字符串,引用 DecimalPrecision 記錄的名稱。

當浮點數與計量單位相關聯時,使用正確的工具以正確的精度比較或舍入值非常重要。

Float類提供了一些靜態方法來實現此目的:

round() 用于將浮點數四舍五入到指定精度。 is_zero() 用于檢查浮點數是否在指定精度下等于零。 compare() 用于比較兩個浮點數在指定精度下的大小。

示例

按照計量單位的精度四舍五入數量:

fields.Float.round(self.product_uom_qty, precision_rounding=self.product_uom_id.rounding)

使用計量單位的精度檢查數量是否為零:

fields.Float.is_zero(self.product_uom_qty, precision_rounding=self.product_uom_id.rounding)

比較兩個數量:

field.Float.compare(self.product_uom_qty, self.qty_done, precision_rounding=self.product_uom_id.rounding)

比較助手出于歷史目的使用 __cmp__ 語義,因此使用此助手的適當、慣用方式如下:

如果result == 0,則第一個和第二個浮點數相等;如果result < 0,則第一個浮點數小于第二個;如果result > 0,則第一個浮點數大于第二個。

class odoo.fields.Integer[源代碼]?

封裝了一個 int 。

高級字段?

class odoo.fields.Binary[源代碼]?

封裝二進制內容(例如文件)。

參數

attachment (bool) – 字段是否應存儲為 ir_attachment 或模型表的列(默認值: True )。

class odoo.fields.Html[源代碼]?

封裝 HTML 代碼內容。

參數
  • sanitize (bool) – 值是否需要進行過濾(默認值: True

  • sanitize_overridable (bool) – 是否允許屬于 base.group_sanitize_override 用戶組的用戶繞過衛生處理(默認值: False

  • sanitize_tags (bool) – 是否對標簽進行清理(只接受白名單屬性,默認為 True

  • sanitize_attributes (bool) – 是否對屬性進行清理(只接受白名單中的屬性,默認值: True

  • sanitize_style (bool) – 是否清理樣式屬性(默認值: False

  • strip_style (bool) – 是否剝離樣式屬性(被移除并因此未經過消毒, 默認值: False

  • strip_classes (bool) – 是否剝離類屬性(默認值: False

class odoo.fields.Image[源代碼]?

封裝一個圖像,擴展 Binary 。

如果圖像大小超過像素的 max_width / max_height 限制,則圖像將按比例縮小到限制大小。

參數
  • max_width (int) – 圖片的最大寬度(默認值: 0 ,無限制)

  • max_height (int) – 圖片的最大高度(默認值: 0 ,無限制)

  • verify_resolution (bool) – 是否需要驗證圖像分辨率,以確保不超過最大圖像分辨率(默認值: True )。請參見 odoo.tools.image.ImageProcess 獲取最大圖像分辨率(默認值: 50e6 )。

注解

如果未指定 max_width / max_height (或設置為0),并且 verify_resolution 為False,則不會驗證字段內容,應使用 Binary 字段。

class odoo.fields.Monetary[源代碼]?

封裝了一個以給定的 res_currency 表示的 float 。

小數精度和貨幣符號取自 currency_field 屬性。

參數

currency_field (str) – 表示該貨幣字段所使用的 res_currencyMany2one 字段名稱 (默認值: 'currency_id' )

class odoo.fields.Selection[源代碼]?

封裝了不同值之間的互斥選擇。

參數
  • selection (list(tuple(str,str)) or callable or str) – 指定此字段的可能取值??梢允怯梢唤M (value, label) 對組成的列表,也可以是一個模型方法或方法名。

  • selection_add (list(tuple(str,str))) – 提供了在覆蓋字段的情況下選擇的擴展。它是一個由 (value, label)(value,) 成對或單個值的列表,其中單個值必須出現在被覆蓋的選擇中。新值按與被覆蓋選擇一致的順序插入到此列表中: selection = [(‘a’, ‘A’), (‘b’, ‘B’)] selection_add = [(‘c’, ‘C’), (‘b’,)] > result = [(‘a’, ‘A’), (‘c’, ‘C’), (‘b’, ‘B)’]

  • ondelete – 提供了一個回退機制,用于任何帶有selection_add的覆蓋字段。它是一個字典,將selection_add中的每個選項映射到一個回退操作。這個回退操作將應用于所有selection_add選項映射到它的記錄。這些操作可以是以下任何一種: - ‘set null’ – 默認值,所有具有此選項的記錄將其選擇值設置為False。 - ‘cascade’ – 所有具有此選項的記錄將與該選項本身一起被刪除。 - ‘set default’ – 所有具有此選項的記錄將被設置為字段定義的默認值 - ‘set VALUE’ – 所有具有此選項的記錄將被設置為給定值 - <callable> – 一個可調用的函數,其第一個和唯一的參數將是包含指定Selection選項的記錄集,用于自定義處理

屬性 selection 是必需的,除非是 related 或擴展字段的情況。

class odoo.fields.Text[源代碼]?

Char 非常相似,但用于更長的內容,沒有大小,并且通常顯示為多行文本框。

參數

translate (bool or callable) – 啟用字段值的翻譯;使用 translate=True 以整體方式翻譯字段值; translate 也可以是可調用對象,使得 translate(callback, value) 通過使用 callback(term) 來檢索術語的翻譯來翻譯 value 。

日期(時間)字段?

DatesDatetimes 是任何業務應用程序中非常重要的字段。它們的錯誤使用可能會創建看不見但痛苦的錯誤,本節旨在為Odoo開發人員提供避免誤用這些字段所需的知識。

當給日期/時間字段賦值時,以下選項是有效的:

  • 一個 datedatetime 對象。

  • 一個符合服務器格式的字符串:

    • YYYY-MM-DD 適用于 Date 字段,

    • YYYY-MM-DD HH:MM:SS 適用于 Datetime 字段。

  • FalseNone 。

Date和Datetime字段類有助手方法,嘗試轉換為兼容類型:

Example

解析來自外部來源的日期/日期時間::

fields.Date.to_date(self._context.get('date_from'))

日期/時間比較最佳實踐:

  • 日期字段 只能 與日期對象進行比較。

  • Datetime字段 只能 與datetime對象進行比較。

警告

表示日期和日期時間的字符串可以相互比較,但結果可能不是預期的結果,因為日期時間字符串始終大于日期字符串,因此 強烈 不建議這種做法。

常見的日期和時間操作,如加減或獲取周期的開始/結束,都可以通過 DateDatetime 進行操作。這些 助手函數也可以通過導入 odoo.tools.date_utils 來使用。

注解

時區

日期時間字段在數據庫中以 timestamp without timezone 列的形式存儲,并以UTC時區存儲。這是有意設計的,因為它使Odoo數據庫獨立于托管服務器系統的時區。時區轉換完全由客戶端管理。

class odoo.fields.Date[源代碼]?

封裝了一個python date 對象。

static add(value, *args, **kwargs)[源代碼]?

返回 valuerelativedelta 的和。

參數
  • value – 初始日期或日期時間。

  • args – 直接傳遞給 relativedelta 的位置參數。

  • kwargs – 直接傳遞給 relativedelta 的關鍵字參數。

返回

結果日期/日期時間。

static context_today(record, timestamp=None)[源代碼]?

返回當前日期,以客戶端時區為準,格式適合日期字段。

注解

此方法可用于計算默認值。

參數
  • record – 獲取時區的記錄集。

  • timestamp (datetime) – 可選的日期時間值,用于代替當前日期和時間(必須是日期時間,普通日期無法在時區之間轉換)。

返回類型

date

static end_of(value, granularity)[源代碼]?

從日期或日期時間獲取時間段的結束時間。

參數
  • value – 初始日期或日期時間。

  • granularity – 時間段類型字符串,可以是年、季度、月、周、日或小時。

返回

指定時間段開始的日期/日期時間對象。

static start_of(value, granularity)[源代碼]?

從日期或日期時間獲取時間段的開始。

參數
  • value – 初始日期或日期時間。

  • granularity – 時間段的類型,可以是年、季度、月、周、日或小時。

返回

一個對應于指定時間段開始的日期/日期時間對象。

static subtract(value, *args, **kwargs)[源代碼]?

返回 valuerelativedelta 之間的差異。

參數
  • value – 初始日期或日期時間。

  • args – 直接傳遞給 relativedelta 的位置參數。

  • kwargs – 直接傳遞給 relativedelta 的關鍵字參數。

返回

結果日期/日期時間。

static to_date(value)[源代碼]?

嘗試將 value 轉換為 date 對象。

警告

如果傳入的值是一個日期時間對象,它將被轉換為日期對象,所有日期時間特定的信息將會丟失(如時分秒,時區等)。

參數

value (str or date or datetime) – 需要轉換的值。

返回

一個表示 value 的對象。

返回類型

date or None

static to_string(value)[源代碼]?

datedatetime 對象轉換為字符串。

參數

value – 需要轉換的值。

返回

value 轉換為服務器日期格式的字符串,如果 valuedatetime 類型,則小時、分鐘、秒和時區信息將被截斷。

返回類型

str

static today(*args)[源代碼]?

返回ORM所期望的當前日期格式。

注解

此函數可用于計算默認值。

class odoo.fields.Datetime[源代碼]?

封裝了一個python datetime 對象。

static add(value, *args, **kwargs)[源代碼]?

返回 valuerelativedelta 的和。

參數
  • value – 初始日期或日期時間。

  • args – 直接傳遞給 relativedelta 的位置參數。

  • kwargs – 直接傳遞給 relativedelta 的關鍵字參數。

返回

結果日期/日期時間。

static context_timestamp(record, timestamp)[源代碼]?

返回給定的時間戳轉換為客戶端時區。

注解

該方法 不應 作為默認初始化器使用,因為日期時間字段在客戶端顯示時會自動轉換。對于默認值,應使用 now() 。

參數
  • record – 獲取時區的記錄集。

  • timestamp (datetime) – 將表示為UTC的本地日期時間值轉換為客戶端時區。

返回

將時間戳轉換為上下文時區的帶時區感知的日期時間。

返回類型

datetime

static end_of(value, granularity)[源代碼]?

從日期或日期時間獲取時間段的結束時間。

參數
  • value – 初始日期或日期時間。

  • granularity – 時間段類型字符串,可以是年、季度、月、周、日或小時。

返回

指定時間段開始的日期/日期時間對象。

static now(*args)[源代碼]?

以ORM所期望的格式返回當前日期和時間。

注解

此函數可用于計算默認值。

static start_of(value, granularity)[源代碼]?

從日期或日期時間獲取時間段的開始。

參數
  • value – 初始日期或日期時間。

  • granularity – 時間段的類型,可以是年、季度、月、周、日或小時。

返回

一個對應于指定時間段開始的日期/日期時間對象。

static subtract(value, *args, **kwargs)[源代碼]?

返回 valuerelativedelta 之間的差異。

參數
  • value – 初始日期或日期時間。

  • args – 直接傳遞給 relativedelta 的位置參數。

  • kwargs – 直接傳遞給 relativedelta 的關鍵字參數。

返回

結果日期/日期時間。

static to_datetime(value)[源代碼]?

將ORM中的 value 轉換為 datetime 值。

參數

value (str or date or datetime) – 需要轉換的值。

返回

一個表示 value 的對象。

返回類型

datetime or None

static to_string(value)[源代碼]?

datetimedate 對象轉換為字符串。

參數

value (datetime or date) – 需要轉換的值。

返回

value 以服務器的日期時間格式表示為字符串,如果 valuedate 類型,則時間部分為午夜(00:00:00)。

返回類型

str

static today(*args)[源代碼]?

返回當前日期,午夜零點(00:00:00)。

關系型字段?

class odoo.fields.Many2one[源代碼]?

這樣的字段的值是一個大小為0(沒有記錄)或1(單個記錄)的記錄集。

參數
  • comodel_name (str) – 目標模型的名稱 必填 ,除了相關或擴展字段之外。

  • domain – 在客戶端上設置在候選值上的可選域(域或字符串)

  • context (dict) – 在處理該字段時,在客戶端使用的可選上下文

  • ondelete (str) – 當所引用的記錄被刪除時應該采取的操作;可能的取值為: 'set null' , 'restrict' , 'cascade'

  • auto_join (bool) – 是否在通過該字段進行搜索時生成JOIN(默認值: False

  • delegate (bool) – 將其設置為 True ,使得目標模型的字段可以從當前模型訪問(對應于 _inherits

  • check_company (bool) – 在 _check_company() 中標記該字段進行驗證。根據字段屬性添加默認公司域。

class odoo.fields.One2many[源代碼]?

One2many字段;此類字段的值是 comodel_name 中所有記錄的記錄集,其中字段 inverse_name 等于當前記錄。

參數
  • comodel_name (str) – 目標模型的名稱

  • inverse_name (str) – comodel_name 中反向 Many2one 字段的名稱

  • domain – 在客戶端上設置在候選值上的可選域(域或字符串)

  • context (dict) – 在處理該字段時,在客戶端使用的可選上下文

  • auto_join (bool) – 是否在通過該字段進行搜索時生成JOIN(默認值: False

除了相關字段或字段擴展的情況外, comodel_nameinverse_name 屬性是必需的。

class odoo.fields.Many2many[源代碼]?

Many2many字段;此字段的值為記錄集。

參數
  • comodel_name – 目標模型的名稱(字符串),除了相關或擴展字段的情況外,必填

  • relation (str) – 可選的數據庫中存儲關系的表的名稱

  • column1 (str) – 可選的列名稱,用于在表 relation 中引用”這些”記錄

  • column2 (str) – 可選的列名稱,用于指向表 relation 中的”那些”記錄

屬性 relation 、 column1column2 是可選的。如果沒有提供,名稱將從模型名稱自動生成,前提是 model_namecomodel_name 不同!

請注意,在給定模型上具有多個具有隱式關系參數的字段,且具有相同的關聯模型是不被ORM接受的,因為這些字段將使用相同的表。ORM防止兩個many2many字段使用相同的關系參數,除非

  • 兩個字段使用相同的模型、關聯模型和關系參數是明確的;或者

  • 至少有一個字段屬于 _auto = False 的模型。

參數
  • domain – 在客戶端上設置在候選值上的可選域(域或字符串)

  • context (dict) – 在處理該字段時,在客戶端使用的可選上下文

  • check_company (bool) – 在 _check_company() 中標記該字段進行驗證。根據字段屬性添加默認公司域。

class odoo.fields.Command[源代碼]?

One2manyMany2many 字段需要特殊的命令來操作它們實現的關系。

在內部,每個命令都是一個3元組,第一個元素是一個必需的整數,用于標識命令,第二個元素要么是相關記錄的ID,以應用命令(命令更新、刪除、取消鏈接和鏈接),要么是0(命令創建、清除和設置),第三個元素要么是要寫入記錄的“值”(命令創建和更新),要么是相關記錄的新“ids”列表(命令設置),要么是0(命令刪除、取消鏈接、鏈接和清除)。

通過Python,我們鼓勵開發人員通過此命名空間的各種函數來創建新命令。我們還鼓勵開發人員在比較現有命令的第一個元素時使用命令標識符常量名稱。

通過RPC,無法使用函數或命令常量名稱。必須改為編寫字面量3元組,其中第一個元素是命令的整數標識符。

CREATE = 0?
UPDATE = 1?
DELETE = 2?
CLEAR = 5?
SET = 6?
classmethod create(values: dict)[源代碼]?

使用“values”在關聯模型中創建新記錄,并將創建的記錄鏈接到“self”。

Many2many 關系中,會在 comodel 中創建一個唯一的新記錄,使得 self 中的所有記錄都鏈接到新記錄。

One2many 關系中,對于 self 中的每個記錄,都會在關聯模型中創建一個新記錄,以便 self 中的每個記錄都與新記錄中的一個記錄精確關聯。

返回命令三元組 (CREATE, 0, values)

classmethod update(id: int, values: dict)[源代碼]?

在相關記錄上寫入 values 。

返回命令三元組 (UPDATE, id, values)

classmethod delete(id: int)[源代碼]?

從數據庫中刪除相關記錄并刪除其與“self”的關系。

Many2many 關系中,如果記錄仍與其他記錄相關聯,則可能會阻止從數據庫中刪除該記錄。

返回命令三元組 (DELETE, id, 0)

移除 self 和相關記錄之間的關聯關系。

One2many 關系中,如果反向字段設置為 ondelete='cascade' ,則給定記錄將從數據庫中刪除。否則,反向字段的值將設置為 False 并保留記錄。

返回命令三元組 (UNLINK, id, 0)

self 和相關記錄之間建立關聯。

返回命令三元組 (LINK, id, 0)

classmethod clear()[源代碼]?

從與 self 相關的關系中刪除所有記錄。它的行為類似于在每個記錄上執行 unlink 命令。

返回命令三元組 (CLEAR, 0, 0)

classmethod set(ids: list)[源代碼]?

self 的當前關系替換為給定的關系。它的行為類似于在每個已刪除的關系上執行 unlink 命令,然后在每個新關系上執行 link 命令。

返回命令三元組 (SET, 0, ids)

偽關系字段?

class odoo.fields.Reference[源代碼]?

偽關聯字段(數據庫中沒有外鍵)。

字段值以 "res_model,res_id" 的格式存儲在數據庫中,是一個 string 類型的值。

class odoo.fields.Many2oneReference[源代碼]?

偽關聯字段(數據庫中沒有外鍵)。

該字段的值在數據庫中以 integer id的形式存儲。

Reference 字段不同,當前 Many2oneReference 字段需要在一個 Char 字段中指定模型,并在 model_field 屬性中指定該字段的名稱。

參數

model_field (str) – 存儲模型名稱的 Char 的名稱。

計算字段?

可以使用 compute 參數計算字段(而不是直接從數據庫中讀?。?。 必須將計算出的值分配給該字段 。如果它使用其他 字段 的值,則應使用 depends() 指定這些字段。:

from odoo import api
total = fields.Float(compute='_compute_total')

@api.depends('value', 'tax')
def _compute_total(self):
    for record in self:
        record.total = record.value + record.value * record.tax
  • 使用子字段時,依賴項可以是點分路徑:

    @api.depends('line_ids.value')
    def _compute_total(self):
        for record in self:
            record.total = sum(line.value for line in record.line_ids)
    
  • 計算字段默認不會被存儲,只有在請求時才會計算并返回。將 store=True 設置為真將會把它們存儲在數據庫中并自動啟用搜索。

  • 可以通過設置 search 參數來啟用計算字段的搜索功能。該值是一個返回 搜索域 的方法名稱。:

    upper_name = field.Char(compute='_compute_upper', search='_search_upper')
    
    def _search_upper(self, operator, value):
        if operator == 'like':
            operator = 'ilike'
        return [('name', operator, value)]
    

    在執行實際模型搜索之前,處理域時會調用搜索方法。它必須返回等效于條件的域: field operator value 。

  • 默認情況下,計算字段是只讀的。要允許在計算字段上 設置 值,請使用 inverse 參數。它是一個函數名稱,用于反轉計算并設置相關字段:

    document = fields.Char(compute='_get_document', inverse='_set_document')
    
    def _get_document(self):
        for record in self:
            with open(record.get_document_path) as f:
                record.document = f.read()
    def _set_document(self):
        for record in self:
            if not record.document: continue
            with open(record.get_document_path()) as f:
                f.write(record.document)
    
  • 同一方法可以同時計算多個字段,只需在所有字段上使用相同的方法并設置所有字段即可:

    discount_value = fields.Float(compute='_apply_discount')
    total = fields.Float(compute='_apply_discount')
    
    @api.depends('value', 'discount')
    def _apply_discount(self):
        for record in self:
            # compute actual discount from discount percentage
            discount = record.value * record.discount
            record.discount_value = discount
            record.total = record.value - discount
    

警告

雖然可以在多個字段中使用相同的計算方法,但不建議在反向方法中這樣做。

在計算反向關系時, 所有 使用該反向關系的字段都受到保護,這意味著即使它們的值不在緩存中,也無法計算它們的值。

如果訪問這些字段并且它們的值不在緩存中,ORM 將簡單地為這些字段返回默認值 False 。這意味著除了觸發反向方法的字段之外的反向字段的值可能不會給出它們的正確值,這可能會破壞反向方法的預期行為。

自動字段?

Model.id?

標識符 field

如果當前記錄集的長度為1,則返回其中唯一記錄的ID。

否則拋出錯誤。

訪問日志字段?

如果啟用了 _log_access ,這些字段將自動設置和更新??梢越盟员苊庠趯λ鼈儧]有用處的表上創建或更新這些字段。

默認情況下, _log_access 的值與 _auto 相同。

Model.create_date?

記錄創建時間,存儲為 Datetime 類型

Model.create_uid?

記錄創建者,使用 Many2one 字段關聯到 res.users 。

Model.write_date?

記錄上次更新的時間, Datetime

Model.write_uid?

記錄最后更新的用戶, Many2one 指向 res.users 。

警告

_log_access 必須TransientModel 上啟用。

保留字段名稱?

一些字段名稱被保留用于預定義的行為,超出了自動化字段的范疇。當需要相關的行為時,應在模型上定義它們:

Model.name?

_rec_name 的默認值,用于在需要代表性“命名”的上下文中顯示記錄。

Char

Model.active?

切換記錄的全局可見性,如果 active 設置為 False ,則該記錄在大多數搜索和列表中都是不可見的。

Boolean

特殊方法:

toggle_active()[源代碼]?

self 中的記錄上反轉 active 的值。

Model.action_archive()[源代碼]?

調用當前活動記錄的 toggle_active() 方法,將記錄集的 active 屬性設置為 False 。

Model.action_unarchive()[源代碼]?

通過調用當前未激活的記錄的 toggle_active() 方法,將記錄集的 active 屬性設置為 True 。

Model.state?

對象的生命周期階段,由 fields 上的 states 屬性使用。

Selection

Model.parent_id?

_parent_name 的默認值,用于在樹形結構中組織記錄,并在域中啟用 child_ofparent_of 運算符。

Many2one

Model.parent_path?

_parent_store 設置為 True 時,用于存儲反映 _parent_name 樹形結構的值,并優化搜索域中的 child_ofparent_of 運算符。必須使用 index=True 聲明以確保正常運行。

Char

Model.company_id?

Odoo 多公司行為所使用的主字段名稱。

用于 :meth:~odoo.models._check_company 檢查多公司一致性。定義記錄是否在公司之間共享(沒有值)或僅可由給定公司的用戶訪問。

Many2one :type: res_company

記錄集?

與模型和記錄的交互是通過記錄集進行的,記錄集是相同模型的記錄的有序集合。

警告

與其名稱所暗示的相反,目前記錄集中可能包含重復項。這在未來可能會改變。

在模型上定義的方法在記錄集上執行,它們的 self 是一個記錄集:

class AModel(models.Model):
    _name = 'a.model'
    def a_method(self):
        # self can be anything between 0 records and all records in the
        # database
        self.do_operation()

迭代記錄集將產生新的 單個記錄 集合(”單例”),就像在Python字符串上迭代產生單個字符的字符串一樣:

def do_operation(self):
    print(self) # => a.model(1, 2, 3, 4, 5)
    for record in self:
        print(record) # => a.model(1), then a.model(2), then a.model(3), ...

字段訪問?

記錄集提供了一個“Active Record”接口:模型字段可以直接作為屬性從記錄中讀取和寫入。

注解

當在可能包含多個記錄的記錄集上訪問非關系字段時,請使用 mapped()

total_qty = sum(self.mapped('qty'))

字段值也可以像字典項一樣訪問,這比使用動態字段名的 getattr() 更加優雅和安全。設置字段的值會觸發對數據庫的更新:

>>> record.name
Example Name
>>> record.company_id.name
Company Name
>>> record.name = "Bob"
>>> field = "name"
>>> record[field]
Bob

警告

嘗試讀取多個記錄上的字段將會對非關系型字段引發錯誤。

訪問關系字段( Many2one , One2many , Many2many總是 返回一個記錄集,如果字段未設置則為空。

記錄緩存和預取?

Odoo 維護記錄字段的緩存,以便不是每個字段訪問都會發出數據庫請求,這對性能來說是可怕的。以下示例僅查詢第一個語句的數據庫:

record.name             # first access reads value from database
record.name             # second access gets value from cache

為了避免逐個讀取每個記錄的每個字段,Odoo 預取 記錄和字段,遵循一些啟發式規則以獲得良好的性能。一旦必須在給定記錄上讀取一個字段,ORM 實際上會在更大的記錄集上讀取該字段,并將返回的值存儲在緩存中以供以后使用。預取的記錄集通常是通過迭代從中獲取記錄的記錄集。此外,所有簡單存儲的字段(布爾值、整數、浮點數、字符、文本、日期、日期時間、選擇、many2one)都會一起獲??;它們對應于模型表的列,并且可以在同一查詢中高效地獲取。

考慮以下示例,其中 partners 是包含 1000 條記錄的記錄集。如果不使用預取,循環將會向數據庫發出 2000 個查詢。使用預取,只需要發出一個查詢:

for partner in partners:
    print partner.name          # first pass prefetches 'name' and 'lang'
                                # (and other fields) on all 'partners'
    print partner.lang

預取數據也適用于 次要記錄 :當讀取關系字段時,它們的值(即記錄)將被訂閱以進行未來的預取。訪問其中一個次要記錄將預取來自同一模型的所有次要記錄。這使得以下示例僅生成兩個查詢,一個用于合作伙伴,一個用于國家::

countries = set()
for partner in partners:
    country = partner.country_id        # first pass prefetches all partners
    countries.add(country.name)         # first pass prefetches all countries

方法修飾器?

Odoo API 模塊定義了 Odoo 環境和方法修飾符。

odoo.api.autovacuum(method)[源代碼]?

裝飾一個方法,使其被每日自動清理計劃任務(模型“ir.autovacuum”)調用。這通常用于類似垃圾回收的任務,不需要特定的計劃任務。

odoo.api.constrains(*args)[源代碼]?

裝飾一個約束檢查器。

每個參數必須是在檢查中使用的字段名稱:

@api.constrains('name', 'description')
def _check_description(self):
    for record in self:
        if record.name == record.description:
            raise ValidationError("Fields name and description must be different")

在已修改命名字段之一的記錄上調用。

如果驗證失敗,應該引發 ValidationError 異常。

警告

@constrains 僅支持簡單字段名稱,不支持點分名稱(例如關系字段的字段 partner_id.customer ),將被忽略。

僅當裝飾方法中聲明的字段包含在 createwrite 調用中時,才會觸發 @constrains 。這意味著在視圖中不存在的字段在記錄創建期間不會觸發調用。必須覆蓋 create 以確保始終觸發約束(例如,測試值的缺失)。

也可以將單個函數作為參數傳遞。在這種情況下,通過使用模型實例調用該函數來獲取字段名稱。

odoo.api.depends(*args)[源代碼]?

返回一個裝飾器,指定“compute”方法(用于新式函數字段)的字段依賴關系。每個參數必須是由點分隔的字段名稱序列:

pname = fields.Char(compute='_compute_pname')

@api.depends('partner_id.name', 'partner_id.is_company')
def _compute_pname(self):
    for record in self:
        if record.partner_id.is_company:
            record.pname = (record.partner_id.name or "").upper()
        else:
            record.pname = record.partner_id.name

也可以將單個函數作為參數傳遞。在這種情況下,通過使用字段模型調用函數來確定依賴項。

odoo.api.depends_context(*args)[源代碼]?

返回一個裝飾器,指定非存儲“compute”方法的上下文依賴項。每個參數都是上下文字典中的一個鍵:

price = fields.Float(compute='_compute_product_price')

@api.depends_context('pricelist')
def _compute_product_price(self):
    for product in self:
        if product.env.context.get('pricelist'):
            pricelist = self.env['product.pricelist'].browse(product.env.context['pricelist'])
        else:
            pricelist = self.env['product.pricelist'].get_default_pricelist()
        product.price = pricelist._get_products_price(product).get(product.id, 0.0)

所有依賴項必須是可哈希的。以下鍵具有特殊支持:

  • company (上下文中的值或當前公司ID),

  • uid (當前用戶ID和超級用戶標志),

  • active_test (env.context 或 field.context 中的值)。

odoo.api.model(method)[源代碼]?

裝飾一個記錄式方法,其中 self 是一個記錄集,但其內容不相關,只有模型是相關的。這樣一個方法:

@api.model
def method(self, args):
    ...
odoo.api.model_create_multi(method)[源代碼]?

裝飾一個接受字典列表并創建多個記錄的方法。該方法可以使用單個字典或字典列表調用:

record = model.create(vals)
records = model.create([vals, ...])
odoo.api.onchange(*args)[源代碼]?

返回一個裝飾器,用于裝飾給定字段的 onchange 方法。

在包含該字段的表單視圖中,當給定字段之一被修改時,該方法將被調用。該方法在一個偽記錄上被調用,該記錄包含表單中存在的值。該記錄上的字段賦值會自動發送回客戶端。

每個參數必須是字段名稱:

@api.onchange('partner_id')
def _onchange_partner(self):
    self.message = "Dear %s" % (self.partner_id.name or "")
return {
    'warning': {'title': "Warning", 'message': "What is this?", 'type': 'notification'},
}

如果類型設置為通知,則警告將顯示在通知中。否則,默認情況下將在對話框中顯示。

警告

@onchange 僅支持簡單字段名稱,不支持點分隔的名稱(例如關系字段的字段,如 partner_id.tz ),這些名稱將被忽略

危險

由于 @onchange 返回偽記錄的記錄集,因此在上述記錄集上調用任何一個CRUD方法( create() , read() , write() , unlink() )都是未定義的行為,因為它們可能尚不存在于數據庫中。

相反,只需像上面的示例一樣設置記錄的字段或調用 update() 方法即可。

警告

無法通過onchange修改 one2manymany2many 字段本身。這是Web客戶端的限制 - 請參見 #2693。

odoo.api.ondelete(*, at_uninstall)[源代碼]?

標記一個方法,在 unlink() 執行期間被執行。

這個裝飾器的目的是允許在取消關聯記錄時出現客戶端錯誤,如果從業務角度來看,刪除這些記錄是沒有意義的。例如,用戶不應該能夠刪除已驗證的銷售訂單。

雖然可以通過簡單地覆蓋模型上的 unlink 方法來實現,但它的缺點是與模塊卸載不兼容。在卸載模塊時,覆蓋可能會引發用戶錯誤,但我們不應該關心,因為模塊正在被卸載,因此與模塊相關的 所有 記錄都應該被刪除。

這意味著通過覆蓋 unlink ,有很大的機會使一些表/記錄成為未卸載模塊的剩余數據。這將使數據庫處于不一致的狀態。此外,如果在該數據庫上重新安裝該模塊,則存在沖突的風險。

使用 @ondelete 裝飾的方法應在某些條件下引發錯誤,按照慣例,該方法的名稱應為 _unlink_if_<condition>_unlink_except_<not_condition> 。

@api.ondelete(at_uninstall=False)
def _unlink_if_user_inactive(self):
    if any(user.active for user in self):
        raise UserError("Can't delete an active user!")

# same as above but with _unlink_except_* as method name
@api.ondelete(at_uninstall=False)
def _unlink_except_active_user(self):
    if any(user.active for user in self):
        raise UserError("Can't delete an active user!")
參數

at_uninstall (bool) – 裝飾方法是否應在實現該方法的模塊被卸載時調用。幾乎總是應該為“False”,以避免模塊卸載觸發這些錯誤。

危險

如果您實現的檢查也適用于卸載模塊,請將參數 at_uninstall 僅設置為 True 。

例如,卸載“銷售”模塊時,如果已驗證的銷售訂單被刪除,這并不重要,因為與“銷售”相關的所有數據都應該被刪除,此時應將“at_uninstall”設置為“False”。

然而,如果沒有安裝其他語言,防止刪除默認語言是有意義的,因為刪除默認語言將破壞很多基本行為。在這種情況下, at_uninstall 應該設置為 True 。

odoo.api.returns(model, downgrade=None, upgrade=None)[源代碼]?

返回一個裝飾器,用于返回“model”實例的方法。

參數
  • model – 一個模型名稱,或者 'self' 表示當前模型

  • downgrade – 一個函數 downgrade(self, value, *args, ** kwargs) 用于將記錄樣式的 value 轉換為傳統樣式的輸出

  • upgrade – 一個函數 upgrade(self, value, *args, ** kwargs) ,用于將傳統風格的 value 轉換為記錄風格的輸出

參數 self 、 `` args`` 和 ``* kwargs`` 是以記錄方式傳遞給方法的參數。

該裝飾器將方法輸出適應于API風格:傳統風格的 id 、 idsFalse ,以及記錄風格的記錄集:

@model
@returns('res.partner')
def find_partner(self, arg):
    ...     # return some record

# output depends on call style: traditional vs record style
partner_id = model.find_partner(cr, uid, arg, context=context)

# recs = model.browse(cr, uid, ids, context)
partner_record = recs.find_partner(arg)

請注意,被裝飾的方法必須符合這個約定。

這些裝飾器會自動 繼承 :覆蓋已裝飾方法的方法將使用相同的 @returns(model) 進行裝飾。

環境?

class odoo.api.Environment(cr, uid, context, su=False)[源代碼]?

環境存儲ORM使用的各種上下文數據:

  • cr :當前數據庫游標(用于數據庫查詢);

  • uid :當前用戶ID(用于訪問權限檢查);

  • context :當前上下文字典(任意元數據);

  • su : 是否處于超級用戶模式。

它通過實現從模型名稱到模型的映射來提供對注冊表的訪問。它還持有記錄的緩存和管理重新計算的數據結構。

>>> records.env
<Environment object ...>
>>> records.env.uid
3
>>> records.env.user
res.user(3)
>>> records.env.cr
<Cursor object ...>

在從另一個記錄集創建記錄集時,環境會被繼承。環境可用于在另一個模型中獲取空記錄集,并查詢該模型:

>>> self.env['res.partner']
res.partner()
>>> self.env['res.partner'].search([('is_company', '=', True), ('customer', '=', True)])
res.partner(7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74)

一些延遲加載的屬性可用于訪問環境(上下文)數據:

Environment.lang?

返回當前語言代碼。

返回類型

str

Environment.user?

返回當前用戶(作為實例)。

返回

當前用戶 - 已使用sudo命令

返回類型

res.users 記錄

Environment.company?

返回當前公司(作為實例)。

如果在上下文中未指定( allowed_company_ids ),則回退到當前用戶的主公司。

引發

AccessError – 無效或未授權的 allowed_company_ids 上下文鍵內容。

返回

當前公司(默認值= self.user.company_id ),與當前環境一起

返回類型

res.company 記錄

警告

在sudo模式下不適用任何健全性檢查!在sudo模式下,用戶可以訪問任何公司,即使不在他允許的公司列表中。

這允許觸發跨公司修改,即使當前用戶沒有訪問目標公司的權限。

Environment.companies?

返回用戶啟用的公司的記錄集。

如果上下文中沒有指定( allowed_company_ids ),則回退到當前用戶的公司。

引發

AccessError – 無效或未授權的 allowed_company_ids 上下文鍵內容。

返回

當前公司(默認為 self.user.company_ids ),與當前環境一起

返回類型

res.company記錄集

警告

在sudo模式下不適用任何健全性檢查!在sudo模式下,用戶可以訪問任何公司,即使不在他允許的公司列表中。

這允許觸發跨公司修改,即使當前用戶沒有訪問目標公司的權限。

有用的環境方法?

Environment.ref(xml_id, raise_if_not_found=True)[源代碼]?

返回與給定的 xml_id 相對應的記錄。

參數
  • xml_id (str) – 記錄的xml_id,格式為 <module.id>

  • raise_if_not_found (bool) – 方法在未找到記錄時是否應該引發異常

返回

找到記錄或無記錄

引發

ValueError – 如果記錄未找到且 raise_if_not_found 為 True

Environment.is_superuser()[源代碼]?

返回環境是否處于超級用戶模式。

Environment.is_admin()[源代碼]?

返回當前用戶是否擁有“訪問權限”組或處于超級用戶模式。

Environment.is_system()[源代碼]?

返回當前用戶是否擁有“設置”組或處于超級用戶模式。

修改環境?

Model.with_context([context][, **overrides]) Model[源代碼]?

返回一個新版本的記錄集,附加到擴展上下文。

擴展上下文是指提供的 context 中合并 overrides 或者 當前 上下文中合并 overrides ,例如:

# current context is {'key1': True}
r2 = records.with_context({}, key2=True)
# -> r2._context is {'key2': True}
r2 = records.with_context(key2=True)
# -> r2._context is {'key1': True, 'key2': True}
Model.with_user(user)[源代碼]?

返回一個新的記錄集,附加到給定用戶,以非超級用戶模式,除非 user 是超級用戶(按照慣例,超級用戶始終處于超級用戶模式。)

Model.with_company(company)[源代碼]?

返回一個帶有修改上下文的新記錄集版本,使其如下所示:

result.env.company = company
result.env.companies = self.env.companies | company
參數

company (res_company or int) – 新環境的主公司。

警告

當當前用戶使用未授權的公司時,在非sudo環境下訪問環境中的公司可能會觸發AccessError。

Model.with_env(env)[源代碼]?

返回一個附加到提供環境的新版本記錄集。

參數

env (Environment) –

注解

返回的記錄集與 self 具有相同的預取對象。

Model.sudo([flag=True])[源代碼]?

使用 flag 參數啟用或禁用超級用戶模式,返回一個新版本的記錄集。超級用戶模式不會更改當前用戶,只是繞過訪問權限檢查。

警告

使用 sudo 可能會導致數據訪問跨越記錄規則的邊界,可能會混合本應該被隔離的記錄(例如在多公司環境中來自不同公司的記錄)。

這可能會導致在選擇一個記錄時出現非直觀的結果,例如獲取默認公司或選擇一個物料清單。

注解

返回的記錄集與 self 具有相同的預取對象。

SQL 執行?

在環境中, cr 屬性是當前數據庫事務的游標,允許直接執行 SQL,無論是為了難以使用 ORM 表達的查詢(例如復雜的連接),還是出于性能原因:

self.env.cr.execute("some_sql", params)

警告

執行原始 SQL 會繞過 ORM,從而繞過 Odoo 的安全規則。請確保在使用用戶輸入時對查詢進行過濾,并且如果您不真正需要使用 SQL 查詢,則優先使用 ORM 工具。

關于模型,需要知道的一件重要的事情是它們不一定立即執行數據庫更新。為了性能原因,框架會延遲在修改記錄后重新計算字段的操作。而且一些數據庫更新也會被延遲。因此,在查詢數據庫之前,必須確保它包含了查詢所需的相關數據。這個操作被稱為 flushing ,它執行了預期的數據庫更新。

Example

# make sure that 'partner_id' is up-to-date in database
self.env['model'].flush_model(['partner_id'])

self.env.cr.execute("SELECT id FROM model WHERE partner_id IN %s", [ids])
ids = [row[0] for row in self.env.cr.fetchall()]

在執行每個 SQL 查詢之前,必須刷新該查詢所需的數據。刷新有三個級別,每個級別都有自己的 API??梢运⑿滤袃热?、模型的所有記錄或某些特定記錄。由于延遲更新通??梢蕴岣咝阅?,因此建議在刷新時要 具體 。

Environment.flush_all()[源代碼]?

刷新所有待處理的計算和更新到數據庫。

Model.flush_model(fnames=None)[源代碼]?

處理“self”模型上的待處理計算和數據庫更新。如果給定參數,則該方法保證至少將給定字段刷新到數據庫??梢运⑿赂嘧侄?。

參數

fnames – 可選的要刷新的字段名稱的可迭代對象

Model.flush_recordset(fnames=None)[源代碼]?

處理記錄 self 上的掛起計算和數據庫更新。當給定參數時,該方法保證至少將記錄 self 上的給定字段刷新到數據庫??梢运⑿赂嗟淖侄魏陀涗?。

參數

fnames – 可選的要刷新的字段名稱的可迭代對象

因為模型使用相同的游標,而 Environment 持有各種緩存,因此在使用原始 SQL 修改數據庫時必須使這些緩存失效,否則進一步使用模型可能會變得不一致。在使用 SQL 的 CREATE 、 UPDATEDELETE 時需要清除緩存,但不需要在使用 SELECT 時清除緩存(因為它只是讀取數據庫)。

Example

# make sure 'state' is up-to-date in database
self.env['model'].flush_model(['state'])

self.env.cr.execute("UPDATE model SET state=%s WHERE state=%s", ['new', 'old'])

# invalidate 'state' from the cache
self.env['model'].invalidate_model(['state'])

與刷新類似,可以使整個緩存失效,使模型的所有記錄的緩存失效,或使特定記錄的緩存失效。甚至可以使某些記錄的特定字段或模型的所有記錄的特定字段失效。由于緩存通??梢蕴岣咝阅?,我們建議在使緩存失效時要 具體 。

Environment.invalidate_all(flush=True)[源代碼]?

使所有記錄的緩存失效。

參數

flush – 是否在失效之前刷新掛起的更新。默認為 True ,可確保緩存一致性。除非您知道自己在做什么,否則不要使用此參數。

Model.invalidate_model(fnames=None, flush=True)[源代碼]?

當緩存的值不再與數據庫的值相對應時,使 self 模型的所有記錄的緩存失效。如果給定參數,則僅從緩存中使給定字段失效。

參數
  • fnames – 要使無效的字段名稱的可選可迭代對象

  • flush – 是否在失效之前刷新掛起的更新。默認為 True ,可確保緩存一致性。除非您知道自己在做什么,否則不要使用此參數。

Model.invalidate_recordset(fnames=None, flush=True)[源代碼]?

當緩存的值不再對應數據庫的值時,使 self 中的記錄緩存失效。如果給定參數,則僅使 self 上的給定字段的緩存失效。

參數
  • fnames – 要使無效的字段名稱的可選可迭代對象

  • flush – 是否在失效之前刷新掛起的更新。默認為 True ,可確保緩存一致性。除非您知道自己在做什么,否則不要使用此參數。

上述方法可以使緩存和數據庫保持一致。但是,如果計算字段的依賴關系在數據庫中被修改,就必須通知模型重新計算計算字段??蚣苄枰赖奈ㄒ恍畔⑹?哪些 記錄上的 哪些 字段已經發生了變化。

Example

# make sure 'state' is up-to-date in database
self.env['model'].flush_model(['state'])

# use the RETURNING clause to retrieve which rows have changed
self.env.cr.execute("UPDATE model SET state=%s WHERE state=%s RETURNING id", ['new', 'old'])
ids = [row[0] for row in self.env.cr.fetchall()]

# invalidate the cache, and notify the update to the framework
records = self.env['model'].browse(ids)
records.invalidate_recordset(['state'])
records.modified(['state'])

需要找出哪些記錄已被修改。有許多方法可以做到這一點,可能涉及額外的 SQL 查詢。在上面的示例中,我們利用了 PostgreSQL 的 RETURNING 子句,在不進行額外查詢的情況下檢索信息。在通過失效使緩存一致之后,使用已更新的字段調用已修改記錄上的 modified 方法。

Model.modified(fnames, create=False, before=False)[源代碼]?

通知 self 上的字段將被或已經被修改。必要時會使緩存失效,并準備重新計算依賴的存儲字段。

參數
  • fnames – 在記錄 self 上修改的字段名稱的可迭代對象

  • create – 是否在記錄創建的上下文中調用

  • before – 在修改記錄 self 之前是否調用

常見 ORM 方法?

創建/更新?

Model.create(vals_list) records[源代碼]?

為模型創建新記錄。

新記錄將使用字典列表 vals_list 中的值進行初始化,如有必要,還將使用 default_get() 中的值。

參數

vals_list (Union[list[dict], dict]) – 模型字段的值,以字典列表形式提供:[{‘field_name’: field_value, …}, …]。為了向后兼容, vals_list 可以是一個字典。它被視為單例列表 [vals] ,并返回單個記錄。詳見 write() 。

返回

已創建的記錄

引發
  • AccessError – 如果當前用戶沒有權限創建指定模型的記錄

  • ValidationError – 如果用戶嘗試為選擇字段輸入無效值

  • ValueError – 如果在創建數值中指定的字段名稱不存在。

  • UserError – 如果在對象層次結構中創建了循環,操作的結果(例如將對象設置為其自身的父級)

Model.copy(default=None)[源代碼]?

復制記錄 self 并使用默認值更新它

參數

default (dict) – 在復制記錄的原始值中覆蓋的字段值字典,例如: {'field_name': overridden_value, ...}

返回

新記錄

Model.default_get(fields_list) default_values[源代碼]?

返回 fields_list 中字段的默認值。默認值由上下文、用戶默認值和模型本身決定。

參數

fields_list (list) – 請求默認值的字段名稱

返回

如果字段有默認值,則將字段名稱映射到相應的默認值的字典。

返回類型

dict

注解

未請求的默認值不會被考慮,不需要返回 fields_list 中未包含的字段的值。

Model.name_create(name) record[源代碼]?

通過調用 create() 方法并提供一個值,即新記錄的顯示名稱,來創建一個新記錄。

新記錄將使用適用于此模型的任何默認值進行初始化,或通過上下文提供。 create() 的通常行為適用。

參數

name – 創建記錄的顯示名稱

返回類型

tuple

返回

創建記錄的 name_get() 對值

Model.write(vals)[源代碼]?

使用提供的值更新 self 中的所有記錄。

參數

vals (dict) – 需要更新的字段及其對應的值

引發
  • AccessError – 如果用戶沒有權限修改指定的記錄/字段

  • ValidationError – 如果選擇字段指定了無效值

  • UserError – 如果在對象層次結構中創建了循環,操作的結果(例如將對象設置為其自身的父級)

  • 對于數字字段( Integer , Float ),值應該是相應類型的

  • 對于 Boolean ,值應該是一個 bool

  • 對于 Selection ,值應該與選擇的值匹配(通常是 str ,有時是 int

  • 對于 Many2one ,值應該是要設置的記錄的數據庫標識符

  • 一個 One2manyMany2many 關系字段的期望值是一個 Command 列表,用于操作它們所實現的關系??偣灿?個命令: create() , update() , delete() , unlink() , link() , clear()set() 。

  • For Date~odoo.fields.Datetime ,值應該是日期(時間)或字符串。

    警告

    如果為日期(時間)字段提供字符串,則必須僅使用UTC并按照 odoo.tools.misc.DEFAULT_SERVER_DATE_FORMATodoo.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT 格式化。

  • 其他非關系型字段使用字符串作為值

搜索/讀取?

Model.browse([ids]) records[源代碼]?

在當前環境中,返回提供的參數所對應的記錄集。

self.browse([7, 18, 12])
res.partner(7, 18, 12)
參數

ids (int or iterable(int) or None) – ID(S)

返回

記錄集

Model.search(domain[, offset=0][, limit=None][, order=None][, count=False])[源代碼]?

基于 domain search domain 搜索記錄。

參數
  • domain搜索域 。使用空列表匹配所有記錄。

  • offset (int) – 忽略的結果數量(默認值:無)

  • limit (int) – 返回的最大記錄數(默認:全部)

  • order (str) – 排序字符串

  • count (bool) – 如果為True,則僅計算并返回匹配記錄的數量(默認值:False)

返回

最多返回符合搜索條件的 limit 條記錄

引發

AccessError – 如果用戶無權訪問請求的信息

Model.search_count(domain) int[源代碼]?

返回當前模型中與 提供的篩選條件 匹配的記錄數。

參數
  • domain搜索域 。使用空列表匹配所有記錄。

  • limit – 最大記錄數(上限)(默認:全部)

根據給定的 name 模式和 operator 比較條件,搜索符合可選搜索域( args )的顯示名稱匹配的記錄。

這通常用于基于關系字段的部分值提供建議。應該通常表現為 name_get() 的反向,但這并不保證。

此方法相當于基于“display_name”調用 search() 方法,然后在搜索結果上調用 name_get() 方法。

參數
  • name (str) – 要匹配的名稱模式

  • args (list) – 可選的搜索域(有關語法,請參見 search() ),指定進一步的限制

  • operator (str) – 用于匹配“名稱”的域運算符,例如“like”或“=”。

  • limit (int) – 可選的最大返回記錄數

返回類型

list

返回

返回所有匹配記錄的 (id, text_repr) 對列表。

Model.read([fields])[源代碼]?

讀取 self 中記錄的請求字段,低級/RPC 方法。

參數
  • fields (list) – 返回的字段名稱(默認為所有字段)

  • load (str) – 加載模式,目前唯一的選項是將其設置為“None”以避免加載m2o字段的“name_get”

返回

一個字典列表,將字段名映射到它們的值,每個記錄一個字典

返回類型

list

引發
Model.read_group(domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)[源代碼]?

按照給定的“groupby”字段分組獲取列表視圖中的記錄列表。

參數
  • domain (list) – 搜索域 。使用空列表匹配所有記錄。

  • fields (list) – 在對象指定的列表視圖中存在的字段列表。每個元素都是’字段’(字段名稱,使用默認聚合),或’字段:agg’(使用聚合函數’agg’的聚合字段),或’name:agg(field)’(使用’agg’的聚合字段,并將其作為’name’返回)??赡艿木酆虾瘮凳怯?`PostgreSQL <https://www.postgresql.org/docs/current/static/functions-aggregate.html>`_提供的,并且包括’count_distinct’,其含義如預期。

  • groupby (list) – 記錄將按照分組描述進行分組。分組描述可以是一個字段(那么它將按照該字段進行分組),也可以是一個字符串“field:granularity”。目前,唯一支持的粒度是“day”、“week”、“month”、“quarter”或“year”,并且它們只對日期/時間字段有意義。

  • offset (int) – 可選的跳過記錄數

  • limit (int) – 可選的最大返回記錄數

  • orderby (str) – 可選的 order by 規范,用于覆蓋組的自然排序順序,另請參見 :py search() (目前僅支持many2one字段)

  • lazy (bool) – 如果為真,則結果僅按第一個groupby分組,其余的groupby放在__context鍵中。如果為假,則所有groupby在一次調用中完成。

返回

包含字典列表(每個記錄一個字典),其中包含: * 按 groupby 參數分組的字段值 * __domain:指定搜索條件的元組列表 * __context:帶有 groupby 參數的字典 * __range:(僅限日期/時間)字典,以field_name:granularity為鍵,映射到具有鍵的字典:”from”(包含)和”to”(不包含),映射到組的時間邊界的字符串表示

返回類型

[{‘field_name_1’: value, …}, …]

引發

AccessError – 如果用戶無權訪問請求的信息

字段?

Model.fields_get([allfields][, attributes])[源代碼]?

返回每個字段的定義。

返回的值是一個字典(以字段名為索引)的字典。包括_inherits的字段。字符串、幫助和選擇(如果存在)屬性已翻譯。

參數
  • allfields (list) – 如果為空或未提供,則為所有字段記錄文檔

  • attributes (list) – 每個字段返回的屬性,如果為空或未提供,則返回所有屬性

返回

將字段名稱映射到將屬性映射到值的字典的字典。

返回類型

dict

搜索域?

域是一個條件列表,每個條件都是一個三元組(可以是 listtuple ),其中 (field_name, operator, value) ,其中:

  • field_name ( str )

    當前模型的字段名稱,或通過點符號遍歷 Many2one 關系的字段名稱,例如 'street''partner_id.country'

  • operator ( str )

    用于將 field_namevalue 進行比較的運算符。有效的運算符包括:

    =

    等于

    !=

    不等于

    >

    大于

    >=

    大于或等于

    <

    小于

    <=

    小于或等于

    =?

    未設置或等于(如果 valueNoneFalse ,則返回true,否則的話就像 = 一樣)

    =like

    使用 value 模式匹配 field_name 。模式中的下劃線 _ 代表(匹配)任意單個字符;百分號 % 匹配零個或多個字符的任意字符串。

    like

    field_name%value% 模式進行匹配。類似于 =like ,但在匹配前將 value 用 ‘%’ 包裝

    not like

    不符合 %value% 模式

    ilike

    不區分大小寫的 like

    not ilike

    不區分大小寫的 not like

    =ilike

    不區分大小寫的 =like

    in

    等于 value 中的任何一項, value 應該是一個項目列表

    not in

    value 中的所有項都不相等

    child_of

    value 記錄的子級(后代)(value 可以是一個項目或項目列表)。

    考慮模型的語義(即遵循由 _parent_name 指定的關系字段)。

    parent_of

    value 記錄的父級(祖先)(value 可以是一個項目或項目列表)。

    考慮模型的語義(即遵循由 _parent_name 指定的關系字段)。

  • value

    變量類型,必須可以通過 operator 與命名字段進行比較。

域準則可以使用 前綴 形式的邏輯運算符進行組合:

'&'

邏輯 AND ,默認操作是將相互跟隨的條件組合在一起。Arity 2(使用接下來的2個條件或組合)。

'|'

邏輯 ,參數個數為2。

'!'

邏輯 ,參數個數為1。

注解

主要是為了否定條件的組合。通常,單個條件都有一個否定形式(例如, = -> != , < -> >= ),這比否定肯定形式更簡單。

Example

搜索名為 ABC 的合作伙伴,來自比利時或德國,其語言不是英語的:

[('name','=','ABC'),
 ('language.code','!=','en_US'),
 '|',('country_id.code','=','be'),
     ('country_id.code','=','de')]

該域被解釋為:

    (name is 'ABC')
AND (language is NOT english)
AND (country is Belgium OR Germany)

記錄(集合)信息?

Model.ids?

返回與“self”對應的實際記錄ID列表。

odoo.models.env?

返回給定記錄集的環境。

類型

Environment

Model.exists() records[源代碼]?

返回 self 中存在的記錄子集。它可以用作記錄的測試::

if record.exists():
    ...

按照慣例,新記錄被視為已存在。

Model.ensure_one()[源代碼]?

驗證當前記錄集是否只包含一條記錄。

引發

odoo.exceptions.ValueErrorlen(self) != 1

Model.name_get()[源代碼]?

返回 self 中記錄的文本表示形式,每個輸入記錄輸出一個項目,順序相同。

警告

雖然 name_get() 可以使用上下文數據進行更豐富的上下文格式化,但由于它是 display_name 的默認實現,如果上下文鍵為空/缺失,重置為“默認”行為非常重要。

返回

每個記錄的 (id, text_repr) 列表對

返回類型

list[(int, str)]

Model.get_metadata()[源代碼]?

返回有關給定記錄的一些元數據。

返回

每個請求記錄的所有權字典列表

返回類型

包含以下鍵的字典列表: * id:對象ID * create_uid:創建記錄的用戶 * create_date:記錄創建日期 * write_uid:最后更改記錄的用戶 * write_date:記錄最后更改日期 * xmlid:用于引用此記錄的XML ID(如果有),格式為“module.name” * xmlids:包含xmlid的字典列表,格式為“module.name”,并帶有noupdate布爾值 * noupdate:一個布爾值,指示記錄是否將被更新

操作?

記錄集是不可變的,但是可以使用各種集合操作來組合同一模型的集合,返回新的記錄集。

  • record in set 返回一個布爾值,指示 record (必須是一個只有一個元素的記錄集)是否存在于 set 中。 record not in set 是相反的操作。

  • set1 <= set2set1 < set2 返回 set1 是否是 set2 的子集(嚴格子集)

  • set1 >= set2set1 > set2 返回 set1 是否是 set2 的超集 (分別為嚴格和非嚴格)

  • set1 | set2 返回兩個記錄集的并集,即包含兩個源中存在的所有記錄的新記錄集

  • set1 & set2 返回兩個記錄集的交集,即一個新的記錄集,只包含兩個源中都存在的記錄

  • set1 - set2 返回一個新的記錄集,其中僅包含 set1 中不在 set2 中的記錄

Recordsets是可迭代的,因此可以使用通常的Python工具進行轉換( map() , sorted() , ifilter() ,…),但這些工具返回的是一個 list 或一個 iterator ,因此無法在其結果上調用方法或使用集合操作。

因此,記錄集提供以下操作,返回記錄集本身(如果可能):

篩選?

Model.filtered(func)[源代碼]?

返回滿足 funcself 中的記錄。

參數

func (callable or str) – 一個函數或由字段名用點號分隔的序列

返回

符合條件的記錄集,可能為空。

# only keep records whose company is the current user's
records.filtered(lambda r: r.company_id == user.company_id)

# only keep records whose partner is a company
records.filtered("partner_id.is_company")
Model.filtered_domain(domain)[源代碼]?

返回滿足篩選條件并保持原有順序的 self 記錄。

參數

domain搜索域 。

地圖?

Model.mapped(func)[源代碼]?

func 應用于 self 中的所有記錄,并將結果作為列表或記錄集返回(如果 func 返回記錄集)。在后一種情況下,返回的記錄集的順序是任意的。

參數

func (callable or str) – 一個函數或由字段名用點號分隔的序列

返回

如果 func 為假,則返回 self;否則返回應用于所有 self 記錄的 func 的結果。

返回類型

list or recordset

# returns a list of summing two fields for each record in the set
records.mapped(lambda r: r.field1 + r.field2)

提供的函數可以是一個字符串,用于獲取字段值:

# returns a list of names
records.mapped('name')

# returns a recordset of partners
records.mapped('partner_id')

# returns the union of all partner banks, with duplicates removed
records.mapped('partner_id.bank_ids')

注解

自V13版本開始,支持多關系字段訪問,并且與映射調用類似:

records.partner_id  # == records.mapped('partner_id')
records.partner_id.bank_ids  # == records.mapped('partner_id.bank_ids')
records.partner_id.mapped('name')  # == records.mapped('partner_id.name')

排序?

Model.sorted(key=None, reverse=False)[源代碼]?

按照 key 排序返回記錄集 self 。

參數
  • key (callable or str or None) – 可以是一個接受一個參數并返回每個記錄比較鍵的函數,也可以是字段名,或者是 None ,在這種情況下,記錄將按照默認模型的順序排序

  • reverse (bool) – 如果為 True ,則以相反的順序返回結果

# sort records by name
records.sorted(key=lambda r: r.name)

繼承和擴展?

Odoo 提供了三種不同的機制以模塊化的方式擴展模型:

  • 從現有模型創建一個新模型,向副本添加新信息,但保留原始模塊不變

  • 在原地擴展在其他模塊中定義的模型,替換先前的版本

  • 將模型的一些字段委托給其包含的記錄

../../../_images/inheritance_methods1.png

經典繼承?

當同時使用 _inherit_name 屬性時,Odoo 會創建一個新的模型,使用已有的模型 (通過 _inherit 提供) 作為基礎。新模型將從其基礎模型繼承所有字段、方法和元信息(默認值和其他)。

class Inheritance0(models.Model):
    _name = 'inheritance.0'
    _description = 'Inheritance Zero'

    name = fields.Char()

    def call(self):
        return self.check("model 0")

    def check(self, s):
        return "This is {} record {}".format(s, self.name)

class Inheritance1(models.Model):
    _name = 'inheritance.1'
    _inherit = 'inheritance.0'
    _description = 'Inheritance One'

    def call(self):
        return self.check("model 1")

并使用它們:

a = env['inheritance.0'].create({'name': 'A'})
b = env['inheritance.1'].create({'name': 'B'})

a.call()
b.call()

將產生:

“這是模型0記錄A” “這是模型1記錄B”

第二個模型繼承了第一個模型的 check 方法和 name 字段,但是覆蓋了 call 方法,就像使用標準的 Python繼承 一樣。

擴展?

當使用 _inherit 但是不指定 _name 時,新模型會替換現有模型,實質上是在原地擴展。這對于向現有模型(在其他模塊中創建的)添加新字段或方法,或者自定義或重新配置它們(例如更改它們的默認排序順序)非常有用:

class Extension0(models.Model):
_name = 'extension.0'
_description = 'Extension zero'

name = fields.Char(default="A")

class Extension1(models.Model):
_inherit = 'extension.0'

description = fields.Char(default="Extended")
record = env['extension.0'].create({})
record.read()[0]

將產生:

{'name': "A", 'description': "Extended"}

注解

它還將返回各種 自動字段 ,除非它們已被禁用。

委托?

第三種繼承機制提供了更多的靈活性(可以在運行時更改),但是功能較弱:使用 _inherits 屬性將一個模型“委托”給任何在當前模型上未找到的字段查找到“子”模型。委托是通過在父模型上自動設置的 Reference 字段來執行的。

主要區別在于含義。使用委托時,模型 擁有一個 而不是 是一個 ,將關系轉化為組合而不是繼承:

class Screen(models.Model):
    _name = 'delegation.screen'
    _description = 'Screen'

    size = fields.Float(string='Screen Size in inches')

class Keyboard(models.Model):
    _name = 'delegation.keyboard'
    _description = 'Keyboard'

    layout = fields.Char(string='Layout')

class Laptop(models.Model):
    _name = 'delegation.laptop'
    _description = 'Laptop'

    _inherits = {
        'delegation.screen': 'screen_id',
        'delegation.keyboard': 'keyboard_id',
    }

    name = fields.Char(string='Name')
    maker = fields.Char(string='Maker')

    # a Laptop has a screen
    screen_id = fields.Many2one('delegation.screen', required=True, ondelete="cascade")
    # a Laptop has a keyboard
    keyboard_id = fields.Many2one('delegation.keyboard', required=True, ondelete="cascade")
record = env['delegation.laptop'].create({
    'screen_id': env['delegation.screen'].create({'size': 13.0}).id,
    'keyboard_id': env['delegation.keyboard'].create({'layout': 'QWERTY'}).id,
})
record.size
record.layout

將導致:

13.0
'QWERTY'

并且可以直接在委托字段上進行編寫:

record.write({'size': 14.0})

警告

當使用委托繼承時,方法 不會 被繼承,只有字段會被繼承

警告

  • _inherits 已經或多或少地實現了,如果可以的話請避免使用;

  • 鏈式 _inherits 實際上未被實現,我們無法保證最終行為。

字段增量定義?

字段是在模型類上定義的類屬性。如果模型被擴展,也可以通過在子類上重新定義具有相同名稱和相同類型的字段來擴展字段定義。在這種情況下,字段的屬性來自父類,并被子類中給定的屬性覆蓋。

例如,下面的第二個類僅在字段“state”上添加了一個工具提示:

class First(models.Model):
    _name = 'foo'
    state = fields.Selection([...], required=True)

class Second(models.Model):
    _inherit = 'foo'
    state = fields.Selection(help="Blah blah blah")

錯誤管理?

Odoo 異常模塊定義了幾個核心異常類型。

這些類型被RPC層理解。任何其他異常類型在傳遞到RPC層之前都將被視為“服務器錯誤”。

注解

如果您考慮引入新的異常,請查看 odoo.addons.test_exceptions 模塊。

exception odoo.exceptions.AccessDenied(message='Access Denied')[源代碼]?

登錄/密碼錯誤。

注解

沒有追蹤信息。

示例

當您嘗試使用錯誤的密碼登錄時。

exception odoo.exceptions.AccessError(message)[源代碼]?

訪問權限錯誤。

示例

當您嘗試讀取您無權訪問的記錄時。

exception odoo.exceptions.CacheMiss(record, field)[源代碼]?

緩存中缺少值。

示例

當您嘗試在已刷新的緩存中讀取值時。

exception odoo.exceptions.MissingError(message)[源代碼]?

缺少記錄。

示例

當您嘗試在已刪除的記錄上進行寫操作時。

exception odoo.exceptions.RedirectWarning(message, action, button_text, additional_context=None)[源代碼]?

警告,可以重定向用戶而不僅僅是顯示警告消息。

參數
  • message (str) – 異常消息和前端模態框內容

  • action_id (int) – 重定向操作所在的動作的ID

  • button_text (str) – 在觸發重定向的按鈕上放置的文本。

  • additional_context (dict) – 傳遞給 action_id 的參數。例如,可以用于將視圖限制為 active_ids。

exception odoo.exceptions.UserError(message)[源代碼]?

客戶端處理的通用錯誤。

通常情況下,當用戶嘗試在記錄的當前狀態下執行沒有意義的操作時會出現此錯誤。在語義上類似于通用的400 HTTP狀態碼。

exception odoo.exceptions.ValidationError(message)[源代碼]?

違反了Python約束條件。

示例

當您嘗試使用已經存在于數據庫中的登錄名創建新用戶時。