如何在odoo 14

问题描述

我在 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

因此,当我使用此路由接收请求时,一切正常,但假设我想返回一个不同的状态代码,例如 401,我无法使用类型为 json 的路由执行此操作。 我也尝试过波纹管方法,但这种方法的问题是它会停止所有 odoo 未来的请求。

from odoo.http import request,Response
@http.route('/test',**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'}

所以在上面的例子中,如果我将响应状态代码设置为 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))]
    )

如果结果不是错误,则状态代码始终为 200。但是你可以直接改变方法的代码或者使用猴子补丁女巫,如果在结果中指定状态代码不是很重要,不要这样做 ti^^。

一个简单的猴子补丁把它放在你想要这个行为的模块的 __init__.py 中。

from odoo.http import JsonRequest

class JsonRequestPatch(JsonRequest):

    def _json_response(self,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,defautl_code ) or defautl_code,len(body))]
        )
        
        
JsonRequest._json_response = JsonRequestPatch._json_response

在JSON api的结果中,您可以像这样更改状态代码

 def some_controler(self,**kwargs):
        result = ......
        result['very_very_rare_key_here'] = 401
        return result

猴子补丁的风险在于您完全覆盖该方法,如果在新版本的 Odoo 中进行了某些更改,您也必须在您的方法中进行更改。 上面的代码来自odoo 13.0,当我构建一个restfull模块来处理一个使用axios的网站时,我做了很多这样的事情,使用GET女巫不允许在json请求中发送正文。并且 odoo 期望参数在 import apiClient from "../shared/axios.js"; import apimapping from "../shared/apimapping.js"; class ProjectService { getAllProjects = () => { return apiClient.get(apimapping.GET_PROJECTS); }; } class ProjectNames { getAllprojectNames = () => { return apiClient.get(apimapping.GET_PROJECT_NAMES); }; } export default { ProjectService,ProjectNames }; 请求的正文中。