You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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("您无权访问此请求记录,其中包含您无权限的行。")

代码说明

  1. sudo()获取所有行:必须使用sudo()绕过当前用户的权限限制,才能获取到所有行(包括用户看不到的has_access=False的行)。
  2. 逐行权限检查:对每一行调用check_access_rights和check_access_rule,验证用户是否有权限读取该行。
  3. 抛出访问错误:只要存在任何一行用户无权限,立即抛出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:00:04