如何在Odoo日历中服务端强制过滤非参与用户的私有事件
Odoo日历私有事件强制过滤实现方案
原有方案失效原因
- 视图层新增的筛选器属于前端可选控件,所有用户都可以手动取消勾选,本身就不具备强制约束能力,无法满足权限级过滤需求。
- 窗口动作绑定域的方案存在两个核心问题:
- 配置的目标模型错误:你代码里
res_model写的是calendar.event.type(日历事件分类模型),并非实际存储日程数据的calendar.event模型,域自然不会对日程列表生效。 - 窗口动作域仅在用户点击对应菜单入口时生效,用户从首页日历看板、关联字段跳转、接口调用等其他入口访问日程数据时,会直接绕过该域限制,无法实现全局过滤。
- 配置的目标模型错误:你代码里
推荐实现方式:配置记录规则(无代码/低代码,全局强制生效)
记录规则是Odoo ORM层原生的权限过滤机制,所有数据查询请求都会自动拼接规则对应的过滤域,用户无法手动绕过,是实现这类需求的最优方案。
无代码配置步骤
- 开启Odoo开发者模式,进入「设置-技术-安全-记录规则」菜单新建记录
- 按如下参数配置:
- 名称:隐藏非参与人的私有日程
- 关联模型:选择「日历事件」(对应模型
calendar.event) - 生效用户组:选择需要生效的用户范围,一般选所有内部用户即可
- 规则域:填入以下过滤逻辑,界面配置不需要做XML转义
['|', ('privacy','=','public'), '&', ('partner_ids.user_ids', 'in', [user.id]), ('privacy', '=', 'private')] - 保存后规则立即全局生效,所有用户只能看到公开日程,以及自己作为参与人的私有日程。
模块代码实现方式
如果需要通过自定义模块下发该规则,直接在模块的XML文件中添加如下记录即可:
<record id="rule_calendar_event_hide_private_for_non_attendee" model="ir.rule"> <field name="name">Hide private calendar events for non-attendees</field> <field name="model_id" ref="calendar.model_calendar_event"/> <field name="domain_force">['|', ('privacy','=','public'), '&', ('partner_ids.user_ids', 'in', [user.id]), ('privacy', '=', 'private')]</field> <field name="groups" eval="[(4, ref('base.group_user'))]"/> </record>
备选方案:重写模型搜索方法(适配复杂逻辑场景)
如果后续需要在过滤规则中叠加复杂的自定义判断逻辑,可以继承calendar.event模型重写搜索方法,在服务端强制追加过滤条件,示例代码:
from odoo import models, api class CalendarEvent(models.Model): _inherit = 'calendar.event' @api.model def _search(self, domain, offset=0, limit=None, order=None, access_rights_uid=None): # 强制追加私有事件过滤条件 private_filter = [ '|', ('privacy', '=', 'public'), '&', ('privacy', '=', 'private'), ('partner_ids.user_ids', 'in', [self.env.uid]) ] domain += private_filter return super()._search(domain, offset, limit, order, access_rights_uid)
提示:非必要不选择重写搜索方法的方案,记录规则是Odoo原生支持的权限控制方式,升级兼容性更好、维护成本更低。
内容的提问来源于stack exchange,提问作者Wald Sin
相关产品推荐
相关产品推荐

