Django调用外部Python程序的完整项目实战

作者:

文章目录
  • Django 是 Web 框架,但它经常需要与外部脚本互动,例如: 启动某个独立运行的监控脚本 执行训练模型、特征提取脚本 启动 CPU / 内存压力脚本 调用分析脚本并返回结果 运行系统层面的 Python 工具 你的 AIOps 场景就是典型需求:点击前端按钮 → 启动 CPU 压力脚本 → 持续采集数据
  • 假设你想用 Django 前端按钮启动下面这个脚本负载 CPU: # scripts/cpu_stress.py import time def stress(): while True: x = 0 for i in range(10_000_000): x += i # 消耗 CPU time.sleep(0.1) 不要让 Django import 运行,而是让它跑在独立进程:
  • 文章介绍了 Django 调用外部 Python 脚本的三种方法,并通过完整的项目案例展示如何用 Django 前端按钮启动与停止 CPU 压力脚本,同时补充了常见错误、调试技巧、高级实践和背后原理。 到此这篇关于Django调用外部Python程序的文章就介绍到这了,更多相关Django调用外部Python程序内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: 在Python的Django框架中调用方法和处理无效变量 Python3之外部文件调用Django程序操作model等文件实现方式 python使用django调用deepseek api搭建ai网站
  • 目录
    • 一、为什么 Django 需要调用外部 Python 程序
    • 二、三种常见的调用方式
      • 方式 1:直接 import 调用(轻量级)
      • 方式 2:subprocess 启动外部进程(最常用)
      • 方式 3:Django 异步任务(高级版)
    • 三、完整项目实战:用 Django 按钮启动 CPU 负载脚本
      • Step 1:将脚本放入项目目录
      • Step 2:创建启动脚本的 view
      • Step 3:前端按钮示例
    • 四、常见错误示例与调试技巧
      • 错误 1:使用 import 直接运行死循环
      • 错误 2:subprocess 没写绝对路径
      • 错误 3:Windows 进程无法 terminate
      • 调试技巧:查看子进程是否启动
    • 五、生产环境高级技巧
      • 1. 使用日志记录子进程输出
      • 2. 给脚本加锁,避免重复启动
      • 3. 使用 Redis / 数据库存储子进程 PID
      • 4. 避免 SQLite 作为生产数据库
    • 六、背后原理与机制拓展
      • Django 本身不能跑长任务
      • 为什么 subprocess 是最常用方案?
    • 总结

      Django 是 Web 框架,但它经常需要与外部脚本互动,例如:

      • 启动某个独立运行的监控脚本
      • 执行训练模型、特征提取脚本
      • 启动 CPU / 内存压力脚本
      • 调用分析脚本并返回结果
      • 运行系统层面的 Python 工具

      你的 AIOps 场景就是典型需求:
      点击前端按钮 → 启动 CPU 压力脚本 → 持续采集数据

      写一个外部脚本:

      # scripts/calc.py
      def calc():
          return 1 + 1
      

      Django 中调用:

      from scripts.calc import calc
      
      def index(request):
          result = calc()
          return HttpResponse(result)
      

      这种方式最简单,但缺点也明显:

      不能用于启动长期运行的脚本(比如你的压力脚本),因为会阻塞 Django。

      适用于:

      • CPU 压力脚本
      • 特征提取脚本
      • 数据处理脚本
      • 长时间运行程序

      示例:

      import subprocess
      
      def run_script():
          subprocess.Popen(["python", "scripts/load_cpu.py"])
      

      它会启动一个完全独立的 Python 进程,不会阻塞 Django。

      使用 Celery、Django-Q、Huey 等任务队列:

      • 任务会进入队列,不阻塞网页
      • 可以查看任务运行状态
      • 可以重试、监控

      大型公司一般采用这种方式。但对入门来说略复杂。

      假设你想用 Django 前端按钮启动下面这个脚本负载 CPU:

      # scripts/cpu_stress.py
      import time
      
      def stress():
          while True:
              x = 0
              for i in range(10_000_000):
                  x += i  # 消耗 CPU
              time.sleep(0.1)
      

      不要让 Django import 运行,而是让它跑在独立进程:

      project/
        scripts/
            cpu_stress.py
        app/
            views.py
      

      # app/views.py
      import subprocess
      from django.http import JsonResponse
      import os, sys
      
      PROCESS = None
      
      def start_stress(request):
          global PROCESS
          if PROCESS and PROCESS.poll() is None:
              return JsonResponse({"msg": "已在运行中"})
      
          script = os.path.join(os.getcwd(), "scripts", "cpu_stress.py")
          PROCESS = subprocess.Popen([sys.executable, script])
      
          return JsonResponse({"msg": "启动成功"})
      
      
      def stop_stress(request):
          global PROCESS
          if PROCESS:
              PROCESS.terminate()
              PROCESS = None
              return JsonResponse({"msg": "已停止"})
          return JsonResponse({"msg": "没有正在运行的任务"})
      

      <button onclick="fetch('/start_stress').then(r=>r.json()).then(alert)">启动负载</button>
      <button onclick="fetch('/stop_stress').then(r=>r.json()).then(alert)">停止负载</button>
      

      前端只需发起请求,Django 随即启动或终止压力脚本。

      错误写法:

      from scripts.cpu_stress import stress
      
      def start(request):
          stress()  # ❌ 会把 Django 线程卡死
      

      原因:

      压力脚本死循环 → Django 视图无法返回 → 网站挂掉。

      错误写法:

      subprocess.Popen(["python", "cpu_stress.py"])  # ❌ 找不到脚本
      

      正确写法:

      script = os.path.join(os.getcwd(), "scripts", "cpu_stress.py")
      subprocess.Popen([sys.executable, script])
      

      在 Windows 上,某些子进程会继续挂着,可以改为:

      PROCESS.kill()
      

      Linux / WSL:

      ps aux | grep cpu_stress
      

      Windows:

      tasklist | findstr python
      

      这类调试技巧在 AIOps 项目中非常常用。

      subprocess.Popen(
          [sys.executable, script],
          stdout=open("out.log", "w"),
          stderr=open("err.log", "w")
      )
      

      方便你排查模型脚本/压力脚本的问题。

      if PROCESS and PROCESS.poll() is None:
          # 已经在运行中
      

      防止用户疯狂点击按钮导致重复启动多个压力脚本。

      生产环境推荐:

      • Django View 启动脚本
      • 保存 PID 到 Redis
      • 前端通过 PID 判断脚本是否在运行

      你的前端压力脚本会导致 SQLite 锁表问题。
      生产中建议使用:

      • PostgreSQL(最常用)
      • MySQL / MariaDB

      SQLite 不适合频繁写入+多进程并发。

      Django 是典型的:

      • 同步请求 → 同步响应
      • 一个请求不能占用长时间

      所以它天生不适合:

      • 死循环脚本
      • 深度学习训练任务
      • CPU 压力测试脚本
      • 视频特征提取任务

      这类任务应该由:

      • subprocess
      • Celery
      • 后台 Worker

      来完成。

      因为:

      • 独立进程,不影响 Django 主进程
      • 可以 kill / terminate
      • 支持长时间运行
      • 支持日志
      • 支持参数传递
      • Windows / Linux 都能跑

      它是 AIOps 平台后台运行脚本的最基础工具。

      文章介绍了 Django 调用外部 Python 脚本的三种方法,并通过完整的项目案例展示如何用 Django 前端按钮启动与停止 CPU 压力脚本,同时补充了常见错误、调试技巧、高级实践和背后原理。

      到此这篇关于Django调用外部Python程序的文章就介绍到这了,更多相关Django调用外部Python程序内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

      您可能感兴趣的文章:

      • 在Python的Django框架中调用方法和处理无效变量
      • Python3之外部文件调用Django程序操作model等文件实现方式
      • python使用django调用deepseek api搭建ai网站

      站内搜索