Odoo 16自定义模块中跳过hr.leave原write方法指定权限校验
在Odoo 16中跳过hr.leave原生write方法的特定权限校验
针对你需要在自定义模块重写hr.leave的write方法时,跳过原生代码中那段针对已开始请假单的权限校验,同时确保自定义业务逻辑全程执行的需求,这里提供两种可行的实现方案:
方案一:临时赋予权限组绕过校验
这种方式仅临时为当前用户添加假期管理人员权限组,执行原生方法后再恢复原权限,避免过度提升权限影响其他逻辑:
from odoo import models, fields, api, _ from odoo.exceptions import UserError class HrLeaveInherit(models.Model): _inherit = 'hr.leave' def write(self, values): # 优先执行你的自定义业务逻辑,确保这部分代码始终运行 self._execute_custom_logic(values) # 记录用户原有权限组,临时添加假期管理人员权限(如果用户本身没有) original_groups = self.env.user.groups_id is_officer = self.env.user.has_group('hr_holidays.group_hr_holidays_user') or self.env.is_superuser() if not is_officer: officer_group = self.env.ref('hr_holidays.group_hr_holidays_user') self.env.user.groups_id = original_groups | officer_group try: # 调用原生write方法,此时会跳过目标权限校验 super_result = super(HrLeaveInherit, self).write(values) finally: # 恢复用户原有权限组,避免影响后续操作 if not is_officer: self.env.user.groups_id = original_groups return super_result def _execute_custom_logic(self, values): # 这里填入你的自定义业务逻辑代码 # 示例:当修改请假状态时发送内部通知 if 'state' in values: state_label = dict(self._fields['state'].selection).get(values['state']) for leave in self: leave.message_post( body=_('请假单状态已更新为:%s') % state_label, subtype='mail.mt_comment' )
方案二:使用sudo调用原生方法
这种方式更简洁,直接以超级用户身份执行原生write方法,绕过所有权限校验,但需注意会让原生方法以超级用户权限运行:
from odoo import models, api, _ class HrLeaveInherit(models.Model): _inherit = 'hr.leave' def write(self, values): # 先执行自定义业务逻辑,保持原用户权限上下文 self._execute_custom_logic(values) # 以超级用户身份调用原生write方法,绕过权限校验 super_result = super(HrLeaveInherit, self.sudo()).write(values) return super_result def _execute_custom_logic(self, values): # 自定义业务逻辑实现 pass
方案说明
- 两种方案均保证自定义逻辑优先执行,无论原生方法后续是否有异常(本场景中已跳过目标校验,不会触发对应的
UserError),自定义代码都会运行。 - 方案一适合需要保留原生方法中其他权限校验的场景,仅跳过目标校验;方案二适合无需考虑原生其他权限限制的场景,代码更简洁。
内容的提问来源于stack exchange,提问作者DZEUF
相关产品推荐
相关产品推荐

