外部API
WMS通过模块在内部扩展,但其许多功能和所有数据也可以从外部进行外部分析或与各种工具集成。模型API的一部分可以通过XML-RPC轻松获得,并可从各种语言访问
连接配置
用户
使用管理员帐户登录您的实例。
转到
。单击您要用于XML-RPC访问的用户。
单击操作,然后选择更改密码。
设置新密码值,然后单击更改密码。
使用管理员帐户登录您的实例。
转到
。单击您要用于XML-RPC访问的用户。
单击操作,然后选择更改密码。
设置新密码值,然后单击更改密码。
Python
url = <insert server URL> db = <insert database name> username = 'admin' password = <insert password for your admin user (default: admin)>
Java
final String url = <insert server URL>, db = <insert database name>, username = "admin", password = <insert password for your admin user (default: admin)>;
API密钥
在脚本中使用API密钥的方法是简单地用密钥替换密码。登录名仍在使用中。您应该像存储密码一样小心地存储API密钥,因为它们基本上提供了对您的用户帐户的相同访问权限(尽管它们不能用于通过界面登录)。
要为密钥输入描述,该描述应尽可能清晰完整:这是您以后识别密钥并知道是应该删除它们还是保留它们的唯一方法。
单击生成密钥,然后复制提供的密钥。仔细存储此密钥:它等同于您的密码,就像您的密码一样,系统以后将无法检索或再次显示密钥。如果您丢失了此密钥,则必须创建一个新密钥(并可能删除您丢失的密钥)。
一旦您在帐户上配置了密钥,它们将显示在新API密钥按钮上方,您将能够删除它们:
连接登入
要求API的用户在查询大多数数据之前进行身份验证。
xmlrpc/2/common
端点提供不需要身份验证的元调用,例如身份验证本身或获取版本信息。在尝试身份验证之前,要验证连接信息是否正确,最简单的调用是询问服务器的版本。身份验证本身通过authenticate
函数完成,并返回用于身份验证调用而不是登录的用户标识符(uid
)。
Python
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url)) common.version()
Java
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,
}。
Python
uid = common.authenticate(db, username, password, {})
Java
pythonuid = common.authenticate(db, username, password, {})调用方法
第二是xmlrpc/2/对象。它用于通过execute_kw RPC函数调用WMS模型的方法。
对execute_kw
的每次调用都使用以下参数:
要使用的数据库,一个字符串
用户ID(通过authenticate
检索),一个整数
用户的密码,一个字符串
模型名称,一个字符串
方法名称,一个字符串
按位置传递的参数数组/列表
按关键字传递的参数映射/dict(可选)
示例:
例如,为了看看我们是否可以读取res.partner
模型,我们可以调用check_access_rights
,operation
由位置传递, raise_exception
由关键字传递(以获得真/假结果,而不是真/错误):
python
models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url)) models.execute_kw(db, uid, password, 'res.partner', 'check_access_rights', ['read'], {'raise_exception': False})python
Java
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()
获取强制域过滤器(可能为空),并返回与过滤器匹配的所有记录的数据库标识符。
示例:列出客户公司,例如
Python
models.execute_kw(db,uid,password,'res.partner','search',[[['is_company','=',True]]])
Java
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
参数仅可用于检索所有匹配记录的子集
示例:列出客户公司,例如
Python
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'offset': 10, 'limit': 5})Java
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()
相同的域过滤器,而没有其他参数。。
示例:
Python
models.execute_kw(db, uid, password, 'res.partner', 'search_count', [[['is_company', '=', True]]])
Java
(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()
返回),以及可选的要获取的字段列表。默认情况下,它会获取当前用户可以读取的所有字段,这往往数量很大。
示例:
Python
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)
Java
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
相反,只挑选三个被认为有趣的领域
Python
models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {'fields': ['name', 'country_id', 'comment']})
Java
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
(以了解要期望哪些值,或在更新记录时发送)。
示例:
Python
models.execute_kw(db, uid, password, 'res.partner', 'fields_get', [], {'attributes': ['string', 'help', 'type']})
Java
(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()
如果没有提供该列表,它将获取匹配记录的所有字段)。
示例:
Python
models.execute_kw(db, uid, password, 'res.partner', 'search_read', [[['is_company', '=', True]]], {'fields': ['name', 'country_id', 'comment'], 'limit': 5})
Java
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()
将字段映射到值,用于初始化记录。对于任何具有默认值且未通过映射参数设置的字段,将使用默认值。
示例:
Python
id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{'name': "New Partner"}])
Java
final Integer id = (Integer)models.execute("execute_kw", asList( db, uid, password, "res.partner", "create", asList(new HashMap() {{ put("name", "New Partner"); }}) ));
结果
78
警告
虽然大多数值类型都是预期的(Integer
为整数,Char
Text
为字符串),
One2many
和Many2many
使用documentation
中详述的writemethod
的特殊命令协议。
更新记录
记录可以使用write()
进行更新。它需要一个记录列表来更新,并将更新的字段映射到类似于create()
值。多个记录可以同时更新,但它们都将为所设置的字段获得相同的值。无法执行“计算”更新(其中设置的值取决于记录的现有值)。
示例:
Python
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]])
Java
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()
来批量删除记录。
示例:
Python
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]]])
Java
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()
查询模型,并且从一开始就使用任意模型,但将大多数模型元数据存储在几个元模型中,这些元模型允许在XML-RPC上查询系统和更改模型和字段(有一些限制)。
ir.model
通过其各个领域提供有关模型的信息。
name
模型的人类可读描述
model
系统中每个模型的名称
state
模型是在Python代码(
base
)中生成的,还是通过创建ir.model
记录(manual
)生成的field_id
通过
One2many
到ir.model.fields的模型字段列表view_ids
access_ids
ir.model
可用于
查询系统是否安装的模型(作为在模型上操作或探索系统内容的先决条件)。
获取有关特定模型的信息(通常通过列出与之关联的字段)。
在RPC上动态创建新模型。
重要
自定义模型名称必须以
x_
开头。必须提供
state
并设置为manual
,否则模型将不会加载。无法向自定义模型添加新方法,只能添加字段。
示例:
Python
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', [],
Java
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)也无法设置。
Python
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]])
Java
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)) ));