如何在Odoo中点击按钮后后台执行Python脚本?
在Odoo中后台执行Python脚本的解决方案
你当前用subprocess.run()会阻塞Odoo进程直到脚本完成,要实现后台执行,可采用以下几种实用方案:
方案1:使用subprocess.Popen脱离主进程控制
subprocess.Popen是非阻塞调用,配合nohup和输出重定向,能让脚本完全在后台运行,不占用Odoo的请求线程:
import subprocess import os def execute_background_script(self): # 可将输出重定向到日志文件,替换/dev/null为实际路径如'/var/log/odoo_script.log' with open(os.devnull, 'w') as dev_null: subprocess.Popen( ["nohup", "python3", "/path-to-script/script.py"], stdout=dev_null, stderr=dev_null, stdin=subprocess.DEVNULL, shell=False )
- 说明:
nohup确保脚本在Odoo进程退出后仍能继续运行;输出重定向避免占用终端资源;shell=False提升安全性,避免命令注入风险。
方案2:使用Odoo作业队列(推荐)
借助Odoo官方生态的queue_job模块,能实现可跟踪、可重试的异步任务,更符合Odoo的业务流程:
- 先安装
queue_job模块:
pip install odoo-queue-job
- 在你的模型中定义异步任务:
from odoo import models, api from odoo.addons.queue_job.job import job class YourCustomModel(models.Model): _name = 'your.custom.model' def button_trigger_script(self): # 将任务加入延迟队列,立即返回响应 self.with_delay()._run_script_as_job() @job def _run_script_as_job(self): # 在此执行脚本逻辑,或调用外部脚本 import subprocess subprocess.run(["python3", "/path-to-script/script.py"], check=False)
- 优势:可在Odoo后台查看任务执行状态、重试失败任务;任务与Odoo进程解耦,不影响前端响应;支持优先级配置。
方案3:使用Python多线程
通过启动独立线程执行脚本,让Odoo主线程继续处理用户请求:
import threading import subprocess def _run_script_thread(): subprocess.run(["python3", "/path-to-script/script.py"], check=False) def button_click_action(self): script_thread = threading.Thread(target=_run_script_thread) script_thread.daemon = True # 可选:线程随Odoo主进程结束而终止 script_thread.start()
- 注意:线程内若涉及Odoo数据库操作,需确保线程安全;不适合长时间运行的任务,避免占用过多系统资源。
通用注意事项
- 权限:Odoo运行用户需拥有脚本文件的执行权限,以及脚本路径的访问权限。
- 日志:若需排查问题,建议将脚本输出重定向到指定日志文件,而非丢弃。
- 安全:禁止将用户输入直接拼接进命令参数,始终使用
shell=False并传递参数列表,避免命令注入攻击。
内容的提问来源于stack exchange,提问作者Ernesto Ruiz
相关产品推荐
相关产品推荐

