Odoo13自定义模块:仅点击保存按钮触发Kafka生产者逻辑
问题分析与解决方案
你之前的代码错误在于主动给当前记录添加了skip_kafka_integration=True上下文,导致后续判断时无论是否是手动保存,都会跳过自定义逻辑。以下是几种可行的解决方法,可根据你的场景选择:
方案一:给保存按钮添加专属上下文(精准控制)
通过修改表单视图的保存按钮,添加专属上下文标识,仅当点击该按钮时触发Kafka逻辑。
1. 修改表单视图XML
给默认保存按钮添加上下文:
<record id="custom_module_form_inherit" model="ir.ui.view"> <field name="name">custom.module.form.inherit</field> <field name="model">custom.module</field> <field name="inherit_id" ref="custom_module.view_custom_module_form"/> <field name="arch" type="xml"> <!-- 给普通保存按钮添加上下文 --> <xpath expr="//button[@name='save']" position="attributes"> <attribute name="context">{'manual_save': True}</attribute> </xpath> <!-- 给保存并关闭按钮添加上下文(可选) --> <xpath expr="//button[@name='save_and_close']" position="attributes"> <attribute name="context">{'manual_save': True}</attribute> </xpath> </field> </record>
2. 修改Python的write方法
判断上下文标识,仅在手动保存时执行Kafka逻辑:
def write(self, vals): res = super(CustomModule, self).write(vals) # 仅当手动保存按钮触发时执行Kafka逻辑 if self.env.context.get('manual_save'): # 你的Kafka生产者发送逻辑写在这里 # 示例:send_to_kafka(record_id=self.id, data=vals) return res
方案二:跳过系统内部触发的write操作
通过上下文标识,自动跳过onchange、compute等系统内部调用的write,仅保留用户手动保存的场景。
def write(self, vals): res = super(CustomModule, self).write(vals) # 跳过onchange、compute等系统内部触发的写入 skip_triggers = ['onchange', 'compute', 'default_set'] if not any(self.env.context.get(trigger) for trigger in skip_triggers): # 执行Kafka发送逻辑 # My custom logic goes here. return res
方案三:利用事务提交钩子(确保数据真正写入后触发)
onchange等操作的write是临时的,不会提交数据库事务;而手动保存会触发事务提交。通过事务提交钩子,仅在数据真正持久化后执行Kafka逻辑。
def write(self, vals): res = super(CustomModule, self).write(vals) # 定义Kafka发送函数 def send_kafka_message(): # 注意:事务提交后需重新获取记录,避免数据不一致 for rec in self: # 构造要发送的数据 send_data = {'record_id': rec.id, 'updated_fields': vals} # 发送到Kafka # kafka_producer.send('your_topic_name', send_data) # 仅在非onchange场景下添加事务提交钩子 if not self.env.context.get('onchange'): self.env.cr.postcommit.add(send_kafka_message) return res
内容的提问来源于stack exchange,提问作者Devam Sanghavi
相关产品推荐
相关产品推荐

