外部 API?

通常情況下,Odoo通過模塊進行內部擴展,但其許多功能和所有數據也可從外部進行分析或與各種工具集成。部分 模型 API 可以通過 XML-RPC 輕松訪問,并且可以從多種語言中訪問。

重要

從 PHP8 開始,默認情況下可能不會提供 XML-RPC 擴展。請查看 手冊 以獲取安裝步驟。

另請參閱

連接?

配置?

如果您已經安裝了Odoo服務器,您可以直接使用它的參數。

重要

對于Odoo在線實例(<domain>.odoo.com),用戶是沒有 本地 密碼的(作為一個人,您是通過Odoo在線認證系統登錄的,而不是通過實例本身)。要在Odoo在線實例上使用XML-RPC,您需要在要使用的用戶帳戶上設置密碼:

  • 使用管理員賬戶登錄您的實例。

  • 前往 設置 ? 用戶和公司 ? 用戶 。

  • 點擊您想要用于 XML-RPC 訪問的用戶。

  • 點擊 操作 ,選擇 修改密碼 。

  • 設置 新密碼 值,然后點擊 更改密碼 。

服務器 URL 是實例的域名(例如 https://mycompany.odoo.com ),數據庫名稱是實例的名稱(例如 mycompany )。用戶名是配置的用戶登錄名,如“更改密碼”屏幕所示。

url = <insert server URL>
db = <insert database name>
username = 'admin'
password = <insert password for your admin user (default: admin)>

API密鑰?

14.0 新版功能.

Odoo支持 API密鑰 ,并且(根據模塊或設置)可能需要這些密鑰來執行Web服務操作。

在腳本中使用 API 密鑰的方法是將您的 **密碼 ** 替換為密鑰。登錄仍在使用中。您應該像密碼一樣小心地存儲 API 密鑰,因為它們基本上提供了與密碼相同的訪問權限(盡管它們不能用于通過界面登錄)。

為了在您的賬戶中添加一個密鑰,只需前往您的 偏好設置 (或 我的個人資料 ):

../../_images/preferences1.png

然后打開 賬戶安全 選項卡,點擊 新建 API 密鑰

../../_images/account-security.png

輸入一個描述以便于識別該密鑰, 該描述應盡可能清晰和完整 :這是您以后識別密鑰、確定是否應該刪除或保留它們的唯一方法。

點擊 生成密鑰 ,然后復制提供的密鑰。 請仔細保存此密鑰 :它相當于您的密碼,就像您的密碼一樣,系統將無法在以后檢索或顯示密鑰。如果您丟失了此密鑰,您將不得不創建一個新的(并可能刪除您丟失的那個)。

一旦您在您的賬戶上配置了密鑰,它們將出現在“ New API Key ”按鈕上方,您將能夠刪除它們:

../../_images/delete-key.png

已刪除的 API 密鑰無法恢復或重置 。您需要生成一個新的密鑰,并更新您使用舊密鑰的所有位置。

測試數據庫?

為了使探索更簡單,您也可以向 https://demo.odoo.com 請求一個測試數據庫:

import xmlrpc.client
info = xmlrpc.client.ServerProxy('https://demo.odoo.com/start').start()
url, db, username, password = info['host'], info['database'], info['user'], info['password']

正在登錄?

Odoo 要求 API 用戶在查詢大多數數據之前進行身份驗證。

xmlrpc/2/common 端點提供元調用,不需要身份驗證,例如身份驗證本身或獲取版本信息。在嘗試進行身份驗證之前,為了驗證連接信息是否正確,最簡單的調用是請求服務器的版本。身份驗證本身是通過 authenticate 函數完成的,并返回用于身份驗證調用的用戶標識符( uid ),而不是登錄。

common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
common.version()

結果:

{
    "server_version": "13.0",
    "server_version_info": [13, 0, 0, "final", 0],
    "server_serie": "13.0",
    "protocol_version": 1,
}
uid = common.authenticate(db, username, password, {})

調用方法?

第二個端點是 xmlrpc/2/object 。它通過 execute_kw RPC 函數用于調用 Odoo 模型的方法。

每次調用 execute_kw 都需要傳入以下參數:

  • 要使用的數據庫,一個字符串

  • 用戶ID(通過 authenticate 檢索),整數

  • 用戶密碼,字符串類型

  • 模型名稱,字符串類型

  • 方法名稱,字符串類型

  • 按位置傳遞的參數數組/列表

  • 一個可選的參數映射/字典,通過關鍵字傳遞

Example

例如,要查看是否可以讀取“res.partner”模型,可以通過位置傳遞“operation”和通過關鍵字傳遞“raise_exception”來調用“check_access_rights”(以獲取真/假結果而不是真/錯誤):

models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
models.execute_kw(db, uid, password, 'res.partner', 'check_access_rights', ['read'], {'raise_exception': False})

結果:

true

列出記錄?

可以通過 search() 方法列出和過濾記錄。

search() 需要一個必填的 domain 過濾器(可能為空),并返回與過濾器匹配的所有記錄的數據庫標識符。

Example

例如,列出客戶公司:

models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]])

結果:

[7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74]

分頁?

默認情況下,搜索將返回與條件匹配的所有記錄的ID,這可能是一個巨大的數字。 offsetlimit 參數可用于僅檢索所有匹配記錄的子集。

Example

models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'offset': 10, 'limit': 5})

結果:

[13, 20, 30, 22, 29]

計算記錄數?

與其檢索可能龐大的記錄列表并對其進行計數,可以使用 search_count() 僅檢索與查詢匹配的記錄數。它使用與 search() 相同的 domain 過濾器,不需要其他參數。

Example

models.execute_kw(db, uid, password, 'res.partner', 'search_count', [[['is_company', '=', True]]])

結果:

19

注解

如果其他用戶正在使用服務器,則調用 search 然后調用 search_count (或反之亦然)可能不會產生一致的結果:存儲的數據可能在調用之間發生了更改。

讀取記錄?

記錄數據可以通過 read() 方法訪問,該方法接受一個id列表(由 search() 返回),并可選地提供要獲取的字段列表。默認情況下,它會獲取當前用戶可以讀取的所有字段,這通常是大量的。

Example

ids = models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'limit': 1})
[record] = models.execute_kw(db, uid, password, 'res.partner', 'read', [ids])
# count the number of fields fetched by default
len(record)

結果:

121

相反,只選擇三個被認為有趣的字段。

models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {'fields': ['name', 'country_id', 'comment']})

結果:

[{"comment": false, "country_id": [21, "Belgium"], "id": 7, "name": "Agrolait"}]

注解

即使未請求 id 字段,它也總是會返回。

列出記錄字段?

fields_get() 可以用于檢查模型的字段,并檢查哪些字段似乎是感興趣的。

由于它返回大量的元信息(也被客戶端程序使用),在打印之前應該進行過濾,對于人類用戶來說,最有趣的項目是“string”(字段的標簽),“help”(如果有的話,幫助文本)和“type”(知道期望哪些值,或在更新記錄時發送哪些值)。

Example

models.execute_kw(db, uid, password, 'res.partner', 'fields_get', [], {'attributes': ['string', 'help', 'type']})

結果:

{
    "ean13": {
        "type": "char",
        "help": "BarCode",
        "string": "EAN13"
    },
    "property_account_position_id": {
        "type": "many2one",
        "help": "The fiscal position will determine taxes and accounts used for the partner.",
        "string": "Fiscal Position"
    },
    "signup_valid": {
        "type": "boolean",
        "help": "",
        "string": "Signup Token is Valid"
    },
    "date_localization": {
        "type": "date",
        "help": "",
        "string": "Geo Localization Date"
    },
    "ref_company_ids": {
        "type": "one2many",
        "help": "",
        "string": "Companies that refers to partner"
    },
    "sale_order_count": {
        "type": "integer",
        "help": "",
        "string": "# of Sales Order"
    },
    "purchase_order_count": {
        "type": "integer",
        "help": "",
        "string": "# of Purchase Order"
    },

搜索和閱讀?

由于這是一個非常常見的任務,Odoo提供了一個 search_read() 快捷方式,顧名思義,它相當于 search()read() 的組合,但避免了執行兩個請求和保留id的麻煩。

它的參數與 search() 相似,但它還可以接受一個 fields 列表(就像 read() 一樣,如果沒有提供該列表,它將獲取匹配記錄的所有字段)。

Example

models.execute_kw(db, uid, password, 'res.partner', 'search_read', [[['is_company', '=', True]]], {'fields': ['name', 'country_id', 'comment'], 'limit': 5})

結果:

[
    {
        "comment": false,
        "country_id": [ 21, "Belgium" ],
        "id": 7,
        "name": "Agrolait"
    },
    {
        "comment": false,
        "country_id": [ 76, "France" ],
        "id": 18,
        "name": "Axelor"
    },
    {
        "comment": false,
        "country_id": [ 233, "United Kingdom" ],
        "id": 12,
        "name": "Bank Wealthy and sons"
    },
    {
        "comment": false,
        "country_id": [ 105, "India" ],
        "id": 14,
        "name": "Best Designers"
    },
    {
        "comment": false,
        "country_id": [ 76, "France" ],
        "id": 17,
        "name": "Camptocamp"
    }
]

創建記錄?

使用 create() 方法可以創建一個模型的記錄。該方法會創建一個單獨的記錄并返回其數據庫標識符。

create() 接受一個字段到值的映射,用于初始化記錄。對于任何具有默認值且未通過映射參數設置的字段,將使用默認值。

Example

id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{'name': "New Partner"}])

結果:

78

警告

雖然大多數值類型都是您所期望的(例如 Integer 表示整數, CharText 表示字符串),

更新記錄?

可以使用 write() 更新記錄。它接受一個要更新的記錄列表和一個更新字段到值的映射,類似于 create() 。

可以同時更新多條記錄,但它們將會獲得相同的字段值。無法執行“計算”更新(其中設置的值取決于記錄的現有值)。

Example

models.execute_kw(db, uid, password, 'res.partner', 'write', [[id], {'name': "Newer partner"}])
# get record name after having changed it
models.execute_kw(db, uid, password, 'res.partner', 'name_get', [[id]])

結果:

[[78, "Newer partner"]]

刪除記錄?

可以通過將記錄的ID提供給 unlink() 來批量刪除記錄。

Example

models.execute_kw(db, uid, password, 'res.partner', 'unlink', [[id]])
# check if the deleted record is still in the database
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['id', '=', id]]])

結果:

[]

檢查和內省?

之前我們使用 fields_get() 查詢模型,從一開始就使用了任意模型,但是Odoo將大部分模型元數據存儲在幾個元模型中,這些元模型允許通過XML-RPC動態查詢系統并更改模型和字段(有一些限制)。

ir.model?

通過其各種字段提供有關Odoo模型的信息。

name

模型的人類可讀描述

model

系統中每個模型的名稱

state

模型是在Python代碼中生成的( base )還是通過創建 ir.model 記錄( manual )生成的

field_id

通過 One2many 列出模型的字段,參見 ir.model.fields

view_ids

One2many 字段關聯到模型定義的 視圖

access_ids

與模型上設置的 訪問權限 安全訪問控制列表相關的 One2many 關系

ir.model 可以用于

  • 查詢系統中已安裝的模型(作為對模型操作的前提條件或探索系統內容的先決條件)。

  • 獲取特定模型的信息(通常是通過列出與其關聯的字段)。

  • 通過遠程過程調用動態創建新模型。

重要

  • 自定義模型名稱必須以 x_ 開頭。

  • 必須提供 state 并將其設置為 manual ,否則模型將無法加載。

  • 無法向自定義模型添加新的 方法 ,只能添加字段。

Example

一個自定義模型最初只包含所有模型都可用的“內置”字段:

models.execute_kw(db, uid, password, 'ir.model', 'create', [{
    'name': "Custom Model",
    'model': "x_custom_model",
    'state': 'manual',
}])
models.execute_kw(db, uid, password, 'x_custom_model', 'fields_get', [], {'attributes': ['string', 'help', 'type']})

結果:

{
    "create_uid": {
        "type": "many2one",
        "string": "Created by"
    },
    "create_date": {
        "type": "datetime",
        "string": "Created on"
    },
    "__last_update": {
        "type": "datetime",
        "string": "Last Modified on"
    },
    "write_uid": {
        "type": "many2one",
        "string": "Last Updated by"
    },
    "write_date": {
        "type": "datetime",
        "string": "Last Updated on"
    },
    "display_name": {
        "type": "char",
        "string": "Display Name"
    },
    "id": {
        "type": "integer",
        "string": "Id"
    }
}

ir.model.fields?

提供有關Odoo模型字段的信息,并允許添加自定義字段,無需使用Python代碼。

model_id

Many2one 指向 字段所屬的 ir.model

name

字段的技術名稱(用于 readwrite

field_description

字段的用戶可讀標簽(例如,在 fields_get 中的 string

ttype

要創建的字段的 類型

state

該字段是通過 Python 代碼創建的( base )還是通過 ir.model.fields 創建的( manual

required , readonly , translate

在字段上啟用相應的標志

groups

字段級別訪問控制 ,一個 Many2manyres.groups

selection , size , on_delete , relation , relation_field , domain

有關類型特定屬性和自定義,請參閱詳細信息 字段文檔

重要

  • 與自定義模型一樣,只有使用 state="manual" 創建的新字段才會作為實際字段激活在模型上。

  • 無法通過 ir.model.fields 添加計算字段,也無法設置某些字段元信息(默認值,onchange)。

Example

id = models.execute_kw(db, uid, password, 'ir.model', 'create', [{
    'name': "Custom Model",
    'model': "x_custom",
    'state': 'manual',
}])
models.execute_kw(db, uid, password, 'ir.model.fields', 'create', [{
    'model_id': id,
    'name': 'x_name',
    'ttype': 'char',
    'state': 'manual',
    'required': True,
}])
record_id = models.execute_kw(db, uid, password, 'x_custom', 'create', [{'x_name': "test record"}])
models.execute_kw(db, uid, password, 'x_custom', 'read', [[record_id]])

結果:

[
    {
        "create_uid": [1, "Administrator"],
        "x_name": "test record",
        "__last_update": "2014-11-12 16:32:13",
        "write_uid": [1, "Administrator"],
        "write_date": "2014-11-12 16:32:13",
        "create_date": "2014-11-12 16:32:13",
        "id": 1,
        "display_name": "test record"
    }
]