使用call_kw路由调用后端的方法 - xiaohao0576/odoo-doc GitHub Wiki
Odoo开放了一个/web/dataset/call_kw
Controller,允许登陆的用户通过POST方法调用后端的方法,登陆的用户不止是内部用户,Protal用户也算是用户。
注意,只能调用公开的方法,也就是方法名前面带下划线,或者使用了@api.private
装饰器的方法是不能调用的
@http.route(['/web/dataset/call_kw', '/web/dataset/call_kw/<path:path>'], type='json', auth="user", readonly=_call_kw_readonly)
def call_kw(self, model, method, args, kwargs, path=None):
Model = request.env[model]
get_public_method(Model, method)
return call_kw(request.env[model], method, args, kwargs)
def call_kw(model, name, args, kwargs):
""" Invoke the given method ``name`` on the recordset ``model``. """
method = getattr(model, name, None)
if not method:
raise AttributeError(f"The method '{name}' does not exist on the model '{model._name}'")
api = getattr(method, '_api', None)
if api:
# @api.model, @api.model_create -> no ids
recs = model
else:
ids, args = args[0], args[1:]
recs = model.browse(ids)
# altering kwargs is a cause of errors, for instance when retrying a request
# after a serialization error: the retry is done without context!
kwargs = dict(kwargs)
context = kwargs.pop('context', None) or {}
recs = recs.with_context(context)
_logger.debug("call %s.%s(%s)", recs, method.__name__, Params(args, kwargs))
result = getattr(recs, name)(*args, **kwargs)
if api == "model_create":
# special case for method 'create'
result = result.id if isinstance(args[0], Mapping) else result.ids
else:
result = downgrade(method, result, recs, args, kwargs)
return result
https://github.com/odoo/odoo/blob/591c064b856e72a844b822d917572526ff1a57db/odoo/api.py#L512-L540
开发的时候,可以在Chrome的开发者工具的console,使用fetch函数进行调试,下面是例子
fetch('/web/dataset/call_kw', {
method: 'POST', // 指定请求方法为 POST
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'res.partner',
method: 'search_read',
args:[],
kwargs:{},
params: {model:'res.partner', method: 'search_read', args:[], kwargs:{}}
})
})
.then(response => response.json()).then(data => console.log('Success:', data))
.catch(error => console.error('Error:', error));
odoo还有一个controller,允许调用服务器动作,并以json格式返回结果
@route('/web/action/run', type='json', auth="user")
def run(self, action_id, context=None):
if context:
request.update_context(**context)
action = request.env['ir.actions.server'].browse([action_id])
result = action.run()
return clean_action(result, env=action.env) if result else False