Odoo 17自定义API错误消息随用户选择语言切换(支持公开用户)
Odoo 17自定义API错误消息随用户选择语言切换(支持公开用户)
嘿,我正好碰到过类似的场景,给你理清楚怎么解决这个问题!你现在的需求是让公开用户通过自定义API切换语言后,后续的API错误消息也能自动跟着切换成对应的语言,对吧?结合你已经写的代码,咱们一步步调整到位:
一、先把语言切换API的代码补全并优化
你的基础代码已经有了核心的语言验证部分,现在要补上上下文更新和session存储的逻辑,因为公开用户没有登录态,得靠session来维持语言偏好:
@http.route('/api/lang/<lang>', type='http', auth="public", csrf=False, cors='*') def change_lang(self, lang): """ :param lang: supposed to be value of `url_code` field """ try: # 验证并获取合法的语言代码 lang_code = request.env['res.lang']._lang_get_code(lang) # 1. 更新当前请求的上下文语言,让本次请求的翻译立即生效 request.context = dict(request.context, lang=lang_code) # 2. 把语言代码存在session里,后续所有公开API请求都能复用这个设置 request.session['lang'] = lang_code # 返回成功响应,方便前端处理 return request.make_json_response({'status': 'success', 'active_lang': lang_code}) except ValueError as e: # 这里用_()包裹错误消息,会自动根据当前上下文的语言翻译 error_msg = _("Invalid language code provided.") return request.make_json_response({'status': 'error', 'message': error_msg}, status=400)
这里的关键是同时更新request.context和session['lang']:前者保证本次请求的翻译生效,后者让后续请求能记住用户选的语言。
二、所有自定义API的错误消息必须用翻译函数包裹
不管是抛出异常还是直接返回错误提示,一定要用Odoo内置的_()函数来包裹字符串,这样Odoo才会根据当前请求上下文的语言自动匹配翻译文本。举个例子:
@http.route('/api/custom/your_business_action', type='json', auth="public", csrf=False, cors='*') def custom_business_action(self): try: # 假设这里是你的业务逻辑,比如校验参数 required_param = request.jsonrequest.get('required_param') if not required_param: # 用_()包裹错误消息,自动翻译 raise ValueError(_("Missing required parameters.")) # 其他业务操作... return {'status': 'success', 'data': "操作完成"} except Exception as e: # 捕获异常后,直接返回翻译后的消息 return request.make_json_response({'status': 'error', 'message': str(e)}, status=400)
别直接写死字符串,一定要用_(),不然翻译系统根本没法识别!
三、给所有公开API加语言上下文自动绑定
因为公开用户的请求默认不会自动继承session里的语言,所以要在每个公开API的开头,从session里读取保存的语言代码,更新到请求上下文里。嫌麻烦的话可以写个装饰器统一处理:
第一步:定义语言上下文装饰器
from functools import wraps def set_public_user_lang(func): @wraps(func) def wrapper(*args, **kwargs): # 从session获取用户选择的语言,默认用系统默认语言(比如en_US) lang_code = request.session.get('lang', 'en_US') # 更新请求上下文的语言参数 request.context = dict(request.context, lang=lang_code) # 同步更新env的上下文,确保ORM操作也用这个语言 request.env = request.env(context=request.context) return func(*args, **kwargs) return wrapper
第二步:给公开API加上装饰器
@http.route('/api/custom/your_business_action', type='json', auth="public", csrf=False, cors='*') @set_public_user_lang # 加上这个装饰器,自动绑定语言上下文 def custom_business_action(self): # 业务逻辑...
这样一来,所有加了这个装饰器的公开API,都会自动用用户之前切换的语言来翻译错误消息,不用每个API都写重复代码。
四、最后检查翻译文件是否正确配置
你已经创建了.po翻译文件,要确保这几点:
- 翻译文件放在模块的
i18n目录下,文件名要和语言代码对应(比如阿拉伯语是ar.po) - 所有用
_()包裹的错误消息,在.po文件里都有对应的msgid和msgstr - 模块安装/更新后,在Odoo后台的「翻译」菜单里能看到这些翻译已经导入成功
比如阿拉伯语的.po文件里要有:
msgid "Invalid language code provided." msgstr "رمز اللغة المقدم غير صالح." msgid "Missing required parameters." msgstr "معلومات مطلوبة مفقودة."
这样一套操作下来,公开用户切换语言后,后续API返回的错误消息就会自动变成用户选择的语言啦!
备注:内容来源于stack exchange,提问作者scofild54
相关产品推荐
相关产品推荐

