odoo开发 - RPC开发

odoo开发 - RPC

Odoo通常通过模块在内部扩展,但其许多功能及其所有数据也可从外部获得,用于外部分析或与各种工具集成。
QQ20190122-131208.png
配置
如果您已经安装了Odoo服务器,则可以使用其参数,

警告
对于Odoo Online实例(<domain> .odoo.com),创建用户时没有本地密码(作为对象您通过Odoo Online身份验证系统登录,而不是实例本身)。要在Odoo Online实例上使用XML-RPC,您需要在要使用的用户帐户上设置密码:
· 使用管理员帐户登录您的实例
· 转到Settings ‣ Users ‣ Users
· 单击要用于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)>

登录

Odoo要求API的用户进行身份验证,然后才能查询大多数数据。
xmlrpc/2/common端点提供不需要认证的meta-calls,如认证本身或获取版本信息。要在尝试验证之前验证连接信息是否正确,最简单的方法是询问服务器的版本。认证本身通过该authenticate功能完成,并返回用于认证呼叫而不是登录的用户标识符(uid)。

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

1234
uid = common.authenticate(db, username, password, {})1

调用方法

第二个端点是xmlrpc/2/object,用于通过execute_kw RPC函数调用Odoo的方法。每次调用execute_kw需要以下参数:
· 使用的数据库,一个字符串
· 用户id(通过检索authenticate),一个整数
· 用户密码,字符串
· 型号名称,一个字符串
· 方法名称,字符串
· 一个通过位置传递的参数数组/列表
· 通过关键字传递的参数的映射/字典(可选)

举例看看我们是否可以读取res.partner模型,我们可以通过位置使用operation调用check_access_rights,通过关键字调用raise_exception(为了获得真/假结果,而不是正确/错误)。

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

True

 登录示例代码:

common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(rpc_url))
uid = common.authenticate(rpc_db, username, password, {})
model = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(rpc_url))
print common.version()

输出结果:

{'protocol_version': 1, 'server_version_info': [10, 0, 0, 'final', 0, 'e'], 'server_version': '10.0+e-20181129', 'server_serie': '10.0'}

打印出了odoo版本

列出记录

记录可以通过search()列出和过滤。
search()采用强制 域过滤器(可能为空),并返回与过滤器匹配的所有记录的数据库标识符。举例列出客户公司:

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

分页
默认情况下,搜索将返回与条件匹配的所有记录的id,这可能是一个巨大的数字。offset 和limit参数可用于仅检索所有匹配记录的子集。

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

记录计数

search_count()可以用于仅检索与查询匹配的记录数,而不是检索可能巨大的记录列表并计数它们。当 search()时它需要相同的domain过滤器并且没有其他的参数。

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

警告
如果其他用户正在使用服务器,调用search后调用search_count(或以其他方式)可能不会产生相关的结果:存储的数据可能在呼叫之间发生变化。

阅读数据

阅读记录通过 read()可行,该方法需要一个ids列表(如返回 search())和可选的要获取的字段列表。默认情况下,它将获取当前用户可以读取的所有字段,这往往是一个巨大的数量。

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

相反,只挑选第三个字段

models.execute_kw(db, uid, password,
    'res.partner', 'read',
    [ids], {'fields': ['name', 'country_id', 'comment']})123
[{"comment": false, "country_id": [21, "Belgium"], "id": 7, "name": "Agrolait"}]

注意
就算没有要用id,它还是要返回的。

列出记录字段

fields_get() 可用于检查模型的字段,并检查哪些字段似乎是感兴趣的。
因为它返回大量的元信息(它也被客户端程序使用),它应该在打印前被过滤,用户最干感兴趣的项是string(字段的标签),help (一个帮助文本,如果需要的话),以及type (用于了解哪些值是被期望的,或更新记录时用于发送):

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

搜索和阅读

因为这是一个非常常见的任务,Odoo提供了一个 search_read()快捷方式,其名称建议等同于search()后面一个 read(),但是避免了执行两个请求并保留id。
它的参数类似于search(),但它也可以列出fields(像read(),如果没有提供这个列表,它将获取匹配记录的所有字段):

models.execute_kw(db, uid, password,
    'res.partner', 'search_read',
    [[['is_company', '=', True], ['customer', '=', 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()将字段映射到值,用于初始化记录。对于任何具有默认值且不通过映射参数设置的字段,将使用默认值。

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

警告
大多数值类型是预期的( Integer对应整型, Char 或Text对应字符串 )
· Date, Datetime 和Binary 字段使用字符串值。
· One2many 和Many2many 使用详细的特殊命令协议the documentation to the write method。

更新记录

记录可以使用write(),它需要更新的记录列表和更新的字段映射到的值类似create()。
可以同时更新多个记录,但它们都将为所设置的字段获得相同的值。目前不可能执行“计算的”更新(其中所设置的值取决于记录的现有值)。

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]])

删除数据

可以通过提供其ID到unlink()来批量删除记录 。

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 可以用来
· 查询系统的安装模型(作为模型操作的前提条件或探索系统的内容)
· 获取有关特定模型的信息(通常列出与之相关的字段)
· 通过RPC动态创建新模型

警告
· “自定义”模型名称必须以 x_开始
· state必须被提供和manual,否则模式不会被加载
· 无法向自定义模型添加新方法,只能添加字段。

一个自定义模型,最初只包含所有型号上可用的“内置”字段:

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 –> 该字段的技术名称(用于read或write)
field_description –> 该字段的用户可读标签(例如stringin fields_get)
ttype –> 要创建的字段的类型
state –> 该字段是否通过Python代码(base)或via ir.model.fields(manual)创建,
required,readonly,translate –> 启用字段上的相应标志
groups –> 字段级访问控制, Many2many到res.groups
selection,size,on_delete,relation,relation_field,domain –> 类型特定的属性和自定义,有关详细信息,请参阅字段文档
像自定义模型一样,仅state=”manual”在模型中激活了创建的新字段作为实际字段。

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]])

警告
无法通过ir.model.fields计算字段,某些字段元信息(默认值,onchange)也不能设置

工作流操作

工作流可以通过发送信号来移动。信号是使用 exec_workflow发送的,而不是使用顶级execute_kw.
信号被发送到特定记录,并可能触发与记录关联的工作流实例上的转换。

警告
此示例需要account模块安装

client = models.execute_kw(
    db, uid, password,
    'res.partner', 'search_read',
    [[('customer', '=', True)]],
    {'limit': 1, 'fields': [
        'property_account_receivable_id',
        'property_payment_term_id',
        'property_account_position_id']
    })[0]
invoice_id = models.execute_kw(
    db, uid, password,
    'account.invoice', 'create', [{
        'partner_id': client['id'],
        'account_id': client['property_account_receivable_id'][0],
        'invoice_line_ids': [(0, False, {'name': "AAA"})]
    }])

models.exec_workflow(
    db, uid, password, 'account.invoice', 'invoice_open', invoice_id)

报告打印

搜索ir.actions.report.xml 模型可列出可用报告。
model –> 报告适用的模型可用于查找特定模型的可用报告
name –> 人性化的报告名称
report_name –> 报告的技术名称,用于打印
可以通过RPC打印报告,具有以下信息:
· 报告的名称(report_name)
· 要包括在报告中的记录的ID

invoice_ids = models.execute_kw(
    db, uid, password, 'account.invoice', 'search',
    [[('type', '=', 'out_invoice'), ('state', '=', 'open')]])
report = xmlrpclib.ServerProxy('{}/xmlrpc/2/report'.format(url))
result = report.render_report(
    db, uid, password, 'account.report_invoice', invoice_ids)
report_data = result['result'].decode('base64')

注意
该报告作为以base64编码的PDF二进制数据发送,必须进行解码,并且可能需要在使用前将其保存到磁盘

Last modification:January 23rd, 2019 at 01:06 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment