ODOO中Webhook重复触发问题:如何仅响应自身模块调用而忽略外部请求?
write Method First, let's spot an immediate issue in your current code: you're calling super().write(vals) twice—that's unnecessary and could cause unexpected behavior. We'll fix that along with the loop problem.
The core solution here is to use Odoo's context to flag when the write operation is initiated by your own module. Context is passed along with every record operation, so we can add a custom marker and check for it before running your webhook logic.
Step-by-Step Fix
Add a context marker when your module triggers
write
Whenever your module updates a record (e.g., from a form action, button click, or internal method), pass a custom context key likefrom_my_module: True:# Example: In your module's code where you call write record.write(vals, context={'from_my_module': True})Modify your
writemethod to check the context
Update your overriddenwritemethod to only execute the webhook and message post logic if the context marker exists. Also, remove the duplicatesuper().writecall:def write(self, vals): # First execute the parent write logic once record = super().write(vals) # Check if the write was triggered by our module if self.env.context.get('from_my_module'): self.ensure_one() self.message_post(body="<strong style=\"color: #03355b\">Document Updated</strong>") url = '########' webhook_data = { 'post_title': self.title, 'folder': self.folder, 'post_content': self.post_content, 'portal_id': self.id, 'status': self.status, 'webhook_action': 'update' } response = requests.post( url, data=json.dumps(webhook_data), headers={'Content-Type': 'application/json', 'Authentication': '####'} ) return record
How This Works
- The
contextacts as a flag to distinguish writes from your module vs. external modules. When the external module updates the record (triggered by your webhook), it won't include thefrom_my_modulemarker, so your webhook logic skips execution—breaking the loop. - We fixed the duplicate
super().writecall because calling it twice would apply the same values twice, which is redundant and could lead to unintended side effects.
Bonus: Handle create and unlink Too
You mentioned you inherited create and unlink as well. Apply the same context pattern to those methods to avoid similar loops:
For create:
def create(self, vals): # Pass our context marker when creating the record internally record = super().create(vals) if self.env.context.get('from_my_module'): # Your webhook/message logic for create here pass return record # When creating from your module: new_record = self.env['your.model'].create(vals, context={'from_my_module': True})
For unlink:
def unlink(self): result = super().unlink() if self.env.context.get('from_my_module'): # Your webhook/message logic for unlink here pass return result # When deleting from your module: record.unlink(context={'from_my_module': True})
内容的提问来源于stack exchange,提问作者Luke

