外部 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)>
url = <insert server URL>
db = <insert database name>
username = "admin"
password = <insert password for your admin user (default: admin)>
$url = <insert server URL>;
$db = <insert database name>;
$username = "admin";
$password = <insert password for your admin user (default: admin)>;
final String 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 密鑰,因為它們基本上提供了與密碼相同的訪問權限(盡管它們不能用于通過界面登錄)。
為了在您的賬戶中添加一個密鑰,只需前往您的 偏好設置 (或 我的個人資料 ):

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

輸入一個描述以便于識別該密鑰, 該描述應盡可能清晰和完整 :這是您以后識別密鑰、確定是否應該刪除或保留它們的唯一方法。
點擊 生成密鑰 ,然后復制提供的密鑰。 請仔細保存此密鑰 :它相當于您的密碼,就像您的密碼一樣,系統將無法在以后檢索或顯示密鑰。如果您丟失了此密鑰,您將不得不創建一個新的(并可能刪除您丟失的那個)。
一旦您在您的賬戶上配置了密鑰,它們將出現在“ New API Key ”按鈕上方,您將能夠刪除它們:

已刪除的 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']
require "xmlrpc/client"
info = XMLRPC::Client.new2('https://demo.odoo.com/start').call('start')
url, db, username, password = info['host'], info['database'], info['user'], info['password']
require_once('ripcord.php');
$info = ripcord::client('https://demo.odoo.com/start')->start();
list($url, $db, $username, $password) = array($info['host'], $info['database'], $info['user'], $info['password']);
注解
這些示例使用 Ripcord 庫,該庫提供了一個簡單的 XML-RPC API。Ripcord 要求在您的 PHP 安裝中啟用 XML-RPC 支持。
由于調用是通過 HTTPS 進行的,因此還需要啟用 `OpenSSL 擴展<https://php.net/manual/en/openssl.installation.php>`_。
final XmlRpcClient client = new XmlRpcClient();
final XmlRpcClientConfigImpl start_config = new XmlRpcClientConfigImpl();
start_config.setServerURL(new URL("https://demo.odoo.com/start"));
final Map<String, String> info = (Map<String, String>)client.execute(
start_config, "start", emptyList());
final String url = info.get("host"),
db = info.get("database"),
username = info.get("user"),
password = info.get("password");
正在登錄?
Odoo 要求 API 用戶在查詢大多數數據之前進行身份驗證。
xmlrpc/2/common
端點提供元調用,不需要身份驗證,例如身份驗證本身或獲取版本信息。在嘗試進行身份驗證之前,為了驗證連接信息是否正確,最簡單的調用是請求服務器的版本。身份驗證本身是通過 authenticate
函數完成的,并返回用于身份驗證調用的用戶標識符( uid
),而不是登錄。
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
common.version()
common = XMLRPC::Client.new2("#{url}/xmlrpc/2/common")
common.call('version')
$common = ripcord::client("$url/xmlrpc/2/common");
$common->version();
final XmlRpcClientConfigImpl common_config = new XmlRpcClientConfigImpl();
common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url)));
client.execute(common_config, "version", emptyList());
結果:
{
"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, {})
uid = common.call('authenticate', db, username, password, {})
$uid = $common->authenticate($db, $username, $password, array());
int uid = (int)client.execute(common_config, "authenticate", asList(db, username, password, emptyMap()));
調用方法?
第二個端點是 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})
models = XMLRPC::Client.new2("#{url}/xmlrpc/2/object").proxy
models.execute_kw(db, uid, password, 'res.partner', 'check_access_rights', ['read'], {raise_exception: false})
$models = ripcord::client("$url/xmlrpc/2/object");
$models->execute_kw($db, $uid, $password, 'res.partner', 'check_access_rights', array('read'), array('raise_exception' => false));
final XmlRpcClient models = new XmlRpcClient() {{
setConfig(new XmlRpcClientConfigImpl() {{
setServerURL(new URL(String.format("%s/xmlrpc/2/object", url)));
}});
}};
models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "check_access_rights",
asList("read"),
new HashMap() {{ put("raise_exception", false); }}
));
結果:
true
列出記錄?
可以通過 search()
方法列出和過濾記錄。
search()
需要一個必填的 domain 過濾器(可能為空),并返回與過濾器匹配的所有記錄的數據庫標識符。
Example
例如,列出客戶公司:
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]])
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', true]]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('is_company', '=', true))));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(
asList("is_company", "=", true)))
)));
結果:
[7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74]
分頁?
默認情況下,搜索將返回與條件匹配的所有記錄的ID,這可能是一個巨大的數字。 offset
和 limit
參數可用于僅檢索所有匹配記錄的子集。
Example
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'offset': 10, 'limit': 5})
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', true]]], {offset: 10, limit: 5})
$models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('is_company', '=', true))), array('offset'=>10, 'limit'=>5));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(
asList("is_company", "=", true))),
new HashMap() {{ put("offset", 10); put("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]]])
models.execute_kw(db, uid, password, 'res.partner', 'search_count', [[['is_company', '=', true]]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'search_count', array(array(array('is_company', '=', true))));
(Integer)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search_count",
asList(asList(
asList("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)
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]).first
# count the number of fields fetched by default
record.length
$ids = $models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('is_company', '=', true))), array('limit'=>1));
$records = $models->execute_kw($db, $uid, $password, 'res.partner', 'read', array($ids));
// count the number of fields fetched by default
count($records[0]);
final List ids = asList((Object[])models.execute(
"execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(
asList("is_company", "=", true))),
new HashMap() {{ put("limit", 1); }})));
final Map record = (Map)((Object[])models.execute(
"execute_kw", asList(
db, uid, password,
"res.partner", "read",
asList(ids)
)
))[0];
// count the number of fields fetched by default
record.size();
結果:
121
相反,只選擇三個被認為有趣的字段。
models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {'fields': ['name', 'country_id', 'comment']})
models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {fields: %w(name country_id comment)})
$models->execute_kw($db, $uid, $password, 'res.partner', 'read', array($ids), array('fields'=>array('name', 'country_id', 'comment')));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "read",
asList(ids),
new HashMap() {{
put("fields", asList("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']})
models.execute_kw(db, uid, password, 'res.partner', 'fields_get', [], {attributes: %w(string help type)})
$models->execute_kw($db, $uid, $password, 'res.partner', 'fields_get', array(), array('attributes' => array('string', 'help', 'type')));
(Map<String, Map<String, Object>>)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "fields_get",
emptyList(),
new HashMap() {{
put("attributes", asList("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})
models.execute_kw(db, uid, password, 'res.partner', 'search_read', [[['is_company', '=', true]]], {fields: %w(name country_id comment), limit: 5})
$models->execute_kw($db, $uid, $password, 'res.partner', 'search_read', array(array(array('is_company', '=', true))), array('fields'=>array('name', 'country_id', 'comment'), 'limit'=>5));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search_read",
asList(asList(
asList("is_company", "=", true))),
new HashMap() {{
put("fields", asList("name", "country_id", "comment"));
put("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"}])
id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{name: "New Partner"}])
$id = $models->execute_kw($db, $uid, $password, 'res.partner', 'create', array(array('name'=>"New Partner")));
final Integer id = (Integer)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "create",
asList(new HashMap() {{ put("name", "New Partner"); }})
));
結果:
78
更新記錄?
可以使用 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]])
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]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'write', array(array($id), array('name'=>"Newer partner")));
// get record name after having changed it
$models->execute_kw($db, $uid, $password,
'res.partner', 'name_get', array(array($id)));
models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "write",
asList(
asList(id),
new HashMap() {{ put("name", "Newer Partner"); }}
)
));
// get record name after having changed it
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "name_get",
asList(asList(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]]])
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]]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'unlink', array(array($id)));
// check if the deleted record is still in the database
$models->execute_kw(
$db, $uid, $password, 'res.partner', 'search', array(array(array('id', '=', $id)))
);
models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "unlink",
asList(asList(id))));
// check if the deleted record is still in the database
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(asList("id", "=", 78)))
)));
結果:
[]
檢查和內省?
之前我們使用 fields_get()
查詢模型,從一開始就使用了任意模型,但是Odoo將大部分模型元數據存儲在幾個元模型中,這些元模型允許通過XML-RPC動態查詢系統并更改模型和字段(有一些限制)。
ir.model
?
通過其各種字段提供有關Odoo模型的信息。
name
模型的人類可讀描述
model
系統中每個模型的名稱
state
模型是在Python代碼中生成的(
base
)還是通過創建ir.model
記錄(manual
)生成的field_id
通過
One2many
列出模型的字段,參見 ir.model.fieldsview_ids
access_ids
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']})
$models->execute_kw($db, $uid, $password, 'ir.model', 'create', array(array(
'name' => "Custom Model",
'model' => 'x_custom_model',
'state' => 'manual'
)));
$models->execute_kw($db, $uid, $password, 'x_custom_model', 'fields_get', array(), array('attributes' => array('string', 'help', 'type')));
models.execute_kw(db, uid, password, 'ir.model', 'create', [{
name: "Custom Model",
model: 'x_custom_model',
state: 'manual'
}])
fields = models.execute_kw(db, uid, password, 'x_custom_model', 'fields_get', [], {attributes: %w(string help type)})
models.execute(
"execute_kw", asList(
db, uid, password,
"ir.model", "create",
asList(new HashMap<String, Object>() {{
put("name", "Custom Model");
put("model", "x_custom_model");
put("state", "manual");
}})
));
final Object fields = models.execute(
"execute_kw", asList(
db, uid, password,
"x_custom_model", "fields_get",
emptyList(),
new HashMap<String, Object> () {{
put("attributes", asList(
"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
name
字段的技術名稱(用于
read
或write
)field_description
字段的用戶可讀標簽(例如,在
fields_get
中的string
)ttype
要創建的字段的 類型
state
該字段是通過 Python 代碼創建的(
base
)還是通過ir.model.fields
創建的(manual
)required
,readonly
,translate
在字段上啟用相應的標志
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]])
$id = $models->execute_kw($db, $uid, $password, 'ir.model', 'create', array(array(
'name' => "Custom Model",
'model' => 'x_custom',
'state' => 'manual'
)));
$models->execute_kw($db, $uid, $password, 'ir.model.fields', 'create', array(array(
'model_id' => $id,
'name' => 'x_name',
'ttype' => 'char',
'state' => 'manual',
'required' => true
)));
$record_id = $models->execute_kw($db, $uid, $password, 'x_custom', 'create', array(array('x_name' => "test record")));
$models->execute_kw($db, $uid, $password, 'x_custom', 'read', array(array($record_id)));
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]])
final Integer id = (Integer)models.execute(
"execute_kw", asList(
db, uid, password,
"ir.model", "create",
asList(new HashMap<String, Object>() {{
put("name", "Custom Model");
put("model", "x_custom");
put("state", "manual");
}})
));
models.execute(
"execute_kw", asList(
db, uid, password,
"ir.model.fields", "create",
asList(new HashMap<String, Object>() {{
put("model_id", id);
put("name", "x_name");
put("ttype", "char");
put("state", "manual");
put("required", true);
}})
));
final Integer record_id = (Integer)models.execute(
"execute_kw", asList(
db, uid, password,
"x_custom", "create",
asList(new HashMap<String, Object>() {{
put("x_name", "test record");
}})
));
client.execute(
"execute_kw", asList(
db, uid, password,
"x_custom", "read",
asList(asList(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"
}
]