Aem*_*zai 4 response httpresponse json-rpc python-3.x odoo
我在 odoo 14 中创建了一条 Json 类型的路线。
@http.route('/test', auth='public', methods=['POST'], type="json", csrf=False)
def recieve_data(self, **kw):
headers = request.httprequest.headers
args = request.httprequest.args
data = request.jsonrequest
Run Code Online (Sandbox Code Playgroud)
因此,当我使用此路由收到请求时,一切都很好,但假设我想返回不同的状态代码(如 401),我无法使用类型为 json 的路由来执行此操作。我也尝试过以下方法,但此方法的问题是它会停止所有 odoo 未来的请求。
from odoo.http import request, Response
@http.route('/test', auth='public', methods=['POST'], type="json", csrf=False)
def recieve_data(self, **kw):
headers = request.httprequest.headers
args = request.httprequest.args
data = request.jsonrequest
Response.status = "401 unauthorized"
return {'error' : 'You are not allowed to access the resource'}
Run Code Online (Sandbox Code Playgroud)
因此,在上面的示例中,如果我将响应状态代码设置为 401 ,则所有其他请求(即使它们发送到不同的路由)也将被停止,并且其状态代码更改为 401 。我在odoo14和odoo13中都检查过这个问题。
您无法指定响应的代码,因为您可以看到状态代码被硬编码在http.py:
def _json_response(self, result=None, error=None):
# ......
# ......
return Response(
body, status=error and error.pop('http_status', 200) or 200,
headers=[('Content-Type', mime), ('Content-Length', len(body))]
)
Run Code Online (Sandbox Code Playgroud)
如果结果不是错误,则状态代码始终为200。但是您可以直接更改方法的代码,或者如果在结果中指定状态代码不是很重要,则可以使用猴子补丁女巫,不要这样做 ^^。
一个简单的猴子补丁将其放入__init__.py您想要此行为的模块中。
from odoo.http import JsonRequest
class JsonRequestPatch(JsonRequest):
def _json_response(self, result=None, error=None):
response = {
'jsonrpc': '2.0',
'id': self.jsonrequest.get('id')
}
default_code = 200
if error is not None:
response['error'] = error
if result is not None:
response['result'] = result
# you don't want to remove some key of another result by mistake
if isinstance(response, dict)
defautl_code = response.pop('very_very_rare_key_here', default_code)
mime = 'application/json'
body = json.dumps(response, default=date_utils.json_default)
return Response(
body, status=error and error.pop('http_status', defautl_code ) or defautl_code,
headers=[('Content-Type', mime), ('Content-Length', len(body))]
)
JsonRequest._json_response = JsonRequestPatch._json_response
Run Code Online (Sandbox Code Playgroud)
在 JSON api 的结果中,您可以像这样更改状态代码
def some_controler(self, **kwargs):
result = ......
result['very_very_rare_key_here'] = 401
return result
Run Code Online (Sandbox Code Playgroud)
猴子修补的风险是您完全覆盖该方法,如果新版本中的 Odoo 进行了某些更改,您也必须在您的方法中进行更改。上面的代码来自odoo 13.0我在构建一个restfull模块来与网站一起使用时做了很多这样的事情,该axios网站使用不允许在GET请求中发送正文。odoo 期望参数位于jsonrequest 的主体内部。