Odoo非编辑模式下api.depends对message_follower_ids失效及解决方法咨询
解决Odoo非编辑模式下关注者变更不触发计算字段更新的问题
为什么api.depends对message_follower_ids在非编辑模式下不起作用?
核心原因在于message_follower_ids是关联字段,关注者的添加/移除操作是直接在mail.follower模型上执行的,并没有修改主记录本身的任何字段。Odoo的计算字段依赖跟踪机制,默认只监听当前记录的字段变更事件——主记录没被修改,自然不会触发计算方法的重新执行,哪怕关联的关注者列表变了。
而且非编辑模式下,前端视图不会主动轮询或监听关联记录的变更,所以即使计算字段逻辑正确,也不会自动更新显示。
解决方案:两种可行思路
思路1:通过mail.follower操作触发主记录缓存刷新+前端通知
直接重写mail.follower的create和unlink方法,在关注者变更后,主动刷新主记录的计算字段缓存,并通过Odoo的Bus机制通知前端更新视图。
示例代码(替换your.model.name为你的目标模型):
from odoo import models, fields, api class MailFollower(models.Model): _inherit = 'mail.follower' @api.model def create(self, vals): follower = super().create(vals) # 仅处理目标模型的关注者变更 if follower.res_model == 'your.model.name': main_record = self.env[follower.res_model].browse(follower.res_id) # 刷新目标计算字段的缓存 main_record.invalidate_cache(['has_non_odoo_follower', 'follower_warning']) # 发送Bus通知让前端刷新视图 self.env['bus.bus'].sendone( (self._cr.dbname, 'res.partner', main_record.env.user.partner_id.id), {'type': 'refresh', 'model': follower.res_model, 'res_id': follower.res_id} ) return follower def unlink(self): # 先记录要删除的关注者对应的主记录信息 affected_records = [(f.res_model, f.res_id) for f in self] result = super().unlink() # 遍历处理每个受影响的主记录 for model_name, res_id in affected_records: if model_name == 'your.model.name': main_record = self.env[model_name].browse(res_id) main_record.invalidate_cache(['has_non_odoo_follower', 'follower_warning']) self.env['bus.bus'].sendone( (self._cr.dbname, 'res.partner', main_record.env.user.partner_id.id), {'type': 'refresh', 'model': model_name, 'res_id': res_id} ) return result
思路2:给主模型添加跟踪字段,通过字段变更触发计算
在主模型中新增一个用于跟踪关注者变更的字段,每当关注者添加/移除时,更新这个字段的值——这样主记录本身发生了字段变更,api.depends就能正常触发计算方法,前端视图也会自动刷新。
示例代码:
1. 主模型定义
from odoo import models, fields, api class YourModel(models.Model): _inherit = 'your.model.name' # 用于跟踪关注者变更的字段 follower_update_time = fields.Datetime(default=fields.Datetime.now) has_non_odoo_follower = fields.Boolean(compute='_compute_has_non_odoo_follower') follower_warning = fields.Char(compute='_compute_follower_warning') @api.depends('follower_update_time', 'message_follower_ids') def _compute_has_non_odoo_follower(self): for rec in self: # 判断是否存在非Odoo用户的关注者 non_odoo_followers = rec.message_follower_ids.filtered(lambda f: not f.partner_id.user_id) rec.has_non_odoo_follower = bool(non_odoo_followers) @api.depends('has_non_odoo_follower') def _compute_follower_warning(self): for rec in self: rec.follower_warning = "注意:存在非Odoo系统用户的关注者!" if rec.has_non_odoo_follower else ""
2. 重写mail.follower方法更新跟踪字段
from odoo import models, fields, api class MailFollower(models.Model): _inherit = 'mail.follower' @api.model def create(self, vals): follower = super().create(vals) if follower.res_model == 'your.model.name': self.env[follower.res_model].browse(follower.res_id).write({ 'follower_update_time': fields.Datetime.now() }) return follower def unlink(self): affected_records = [(f.res_model, f.res_id) for f in self] result = super().unlink() for model_name, res_id in affected_records: if model_name == 'your.model.name': self.env[model_name].browse(res_id).write({ 'follower_update_time': fields.Datetime.now() }) return result
为什么之前直接调用计算方法没效果?
你直接调用计算方法时,只是在后端重新计算了字段值,但Odoo会把计算字段的结果缓存起来,而且前端视图没有收到更新通知,所以不会自动刷新显示。必须通过invalidate_cache清除缓存,或者通过修改主记录字段触发内置的更新机制,才能让前端同步最新数据。
内容的提问来源于stack exchange,提问作者ChesuCR
相关产品推荐
相关产品推荐

