如何为Odoo控制器或方法全局设置响应类型?
Odoo 自定义JSON控制器统一响应格式方案
你可以通过自定义装饰器来统一处理整个控制器方法的响应格式,包括异常场景下的JSON返回,避免重复设置content_type。下面是具体实现方案:
1. 定义JSON响应装饰器
这个装饰器会自动捕获异常(比如404),统一返回JSON格式的响应,同时处理正常返回的内容格式:
import json from odoo import http from odoo.http import Response, NotFound def json_response(func): def wrapper(*args, **kwargs): try: result = func(*args, **kwargs) # 处理正常返回:如果是Response对象,确保content_type为JSON;否则直接转JSON if isinstance(result, Response): result.content_type = 'application/json' return result return Response( json.dumps(result, default=str), content_type='application/json' ) except NotFound as e: # 捕获404异常,返回JSON格式错误响应 error_data = { 'error': 'Not Found', 'message': str(e) if str(e) else '请求的资源不存在' } return Response( json.dumps(error_data), content_type='application/json', status=404 ) except Exception as e: # 可选:处理其他异常,返回500 JSON响应 error_data = { 'error': 'Internal Server Error', 'message': str(e) } return Response( json.dumps(error_data), content_type='application/json', status=500 ) return wrapper
2. 改造控制器方法
在控制器方法上应用这个装饰器,之后无需手动处理content_type,直接返回数据结构或抛出异常即可:
class MySuperController(http.Controller): @http.route('/devolive/review/<int:product_id>', method=['GET']) @json_response # 应用自定义装饰器 def get_review_data(self, product_id): # 模拟业务检查逻辑 check = False # 根据实际业务调整条件 if check: # 抛出带自定义消息的404异常 raise NotFound(f"ID为{product_id}的商品评价数据不存在") # 模拟正常返回的业务数据 result = { 'product_id': product_id, 'total_reviews': 2, 'reviews': [ {'user_name': '张三', 'rating': 5, 'content': '这款产品质量很好'}, {'user_name': '李四', 'rating': 4, 'content': '整体不错,细节有待优化'} ] } # 直接返回字典,装饰器会自动转为JSON响应 return result
关键说明
- 正常返回时:方法直接返回字典/列表即可,装饰器会自动完成JSON序列化并设置
content_type;如果需要自定义响应头,也可以手动返回Response对象,装饰器会确保其content_type为JSON。 - 异常场景:抛出
NotFound或其他异常时,装饰器会捕获并返回对应状态码的JSON格式错误信息,替代默认的HTML错误页面。 - 扩展性:可以根据业务需求在装饰器中添加更多异常类型的处理逻辑,比如权限不足的403响应。
内容的提问来源于stack exchange,提问作者olive007
相关产品推荐
相关产品推荐

