Odoo 16中如何基于One2many字段权限限制请求记录访问
Odoo 16 实现请求记录的权限控制:含无权限行则禁止访问
要实现当请求记录包含至少一行用户无访问权限的行时,阻止用户访问该请求记录,可以通过重写请求模型的check_access_rule方法来实现,具体步骤如下:
核心思路
你之前使用的域[('line_ids.has_access', '=', True)]无法生效,原因是行记录的权限规则限制了用户只能看到has_access=True的行,因此在用户上下文里line_ids仅包含有权限的行,该域始终成立。我们需要绕过用户权限获取所有行,逐一检查用户对每行的访问权限,若存在无权限行则抛出访问错误。
实现代码
在请求模型中重写check_access_rule方法:
from odoo import models, api, exceptions class YourRequestModel(models.Model): _inherit = 'your.request.model' # 替换为实际的请求模型名称 @api.model def check_access_rule(self, operation): # 先执行默认的权限检查 super().check_access_rule(operation) # 仅在读取操作时进行行权限校验 if operation == 'read': for request in self: # 使用sudo获取该请求下的所有行(绕过当前用户权限) all_lines = request.sudo().line_ids for line in all_lines: try: # 检查当前用户对该行的读取权限 line.check_access_rights('read') line.check_access_rule('read') except exceptions.AccessError: # 若存在无权限行,抛出错误阻止访问 raise exceptions.AccessError("您无权访问此请求记录,其中包含您无权限的行。")
代码说明
- sudo()获取所有行:必须使用
sudo()绕过当前用户的权限限制,才能获取到所有行(包括用户看不到的has_access=False的行)。 - 逐行权限检查:对每一行调用
check_access_rights和check_access_rule,验证用户是否有权限读取该行。 - 抛出访问错误:只要存在任何一行用户无权限,立即抛出
AccessError,阻止用户访问当前请求记录。
替代方案:计算字段+权限规则
若偏好使用权限规则实现,可创建一个非存储的计算字段标记所有行是否可访问,再在权限规则中引用该字段:
1. 添加计算字段
from odoo import models, fields, api, exceptions class YourRequestModel(models.Model): _inherit = 'your.request.model' all_lines_accessible = fields.Boolean(compute='_compute_all_lines_accessible', store=False) def _compute_all_lines_accessible(self): for request in self: all_lines = request.sudo().line_ids accessible = True for line in all_lines: try: line.check_access_rights('read') line.check_access_rule('read') except exceptions.AccessError: accessible = False break request.all_lines_accessible = accessible
2. 配置权限规则
在请求模型的权限规则中添加域:[('all_lines_accessible', '=', True)]
注意:该方案因使用非存储计算字段,在列表视图包含大量数据时可能存在性能问题,优先推荐第一种重写
check_access_rule的方法。
内容的提问来源于stack exchange,提问作者Jihad92
相关产品推荐
相关产品推荐

