Django調(diào)用外部Python程序的完整項目實(shí)戰(zhàn)
一、為什么 Django 需要調(diào)用外部 Python 程序
Django 是 Web 框架,但它經(jīng)常需要與外部腳本互動,例如:
- 啟動某個獨(dú)立運(yùn)行的監(jiān)控腳本
- 執(zhí)行訓(xùn)練模型、特征提取腳本
- 啟動 CPU / 內(nèi)存壓力腳本
- 調(diào)用分析腳本并返回結(jié)果
- 運(yùn)行系統(tǒng)層面的 Python 工具
你的 AIOps 場景就是典型需求:
點(diǎn)擊前端按鈕 → 啟動 CPU 壓力腳本 → 持續(xù)采集數(shù)據(jù)
二、三種常見的調(diào)用方式
方式 1:直接 import 調(diào)用(輕量級)
寫一個外部腳本:
# scripts/calc.py
def calc():
return 1 + 1
Django 中調(diào)用:
from scripts.calc import calc
def index(request):
result = calc()
return HttpResponse(result)
這種方式最簡單,但缺點(diǎn)也明顯:
不能用于啟動長期運(yùn)行的腳本(比如你的壓力腳本),因?yàn)闀枞?Django。
方式 2:subprocess 啟動外部進(jìn)程(最常用)
適用于:
- CPU 壓力腳本
- 特征提取腳本
- 數(shù)據(jù)處理腳本
- 長時間運(yùn)行程序
示例:
import subprocess
def run_script():
subprocess.Popen(["python", "scripts/load_cpu.py"])
它會啟動一個完全獨(dú)立的 Python 進(jìn)程,不會阻塞 Django。
方式 3:Django 異步任務(wù)(高級版)
使用 Celery、Django-Q、Huey 等任務(wù)隊列:
- 任務(wù)會進(jìn)入隊列,不阻塞網(wǎng)頁
- 可以查看任務(wù)運(yùn)行狀態(tài)
- 可以重試、監(jiān)控
大型公司一般采用這種方式。但對入門來說略復(fù)雜。
三、完整項目實(shí)戰(zhàn):用 Django 按鈕啟動 CPU 負(fù)載腳本
假設(shè)你想用 Django 前端按鈕啟動下面這個腳本負(fù)載 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 運(yùn)行,而是讓它跑在獨(dú)立進(jìn)程:
Step 1:將腳本放入項目目錄
project/
scripts/
cpu_stress.py
app/
views.py
Step 2:創(chuàng)建啟動腳本的 view
# 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": "已在運(yùn)行中"})
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": "沒有正在運(yùn)行的任務(wù)"})
Step 3:前端按鈕示例
<button onclick="fetch('/start_stress').then(r=>r.json()).then(alert)">啟動負(fù)載</button>
<button onclick="fetch('/stop_stress').then(r=>r.json()).then(alert)">停止負(fù)載</button>
前端只需發(fā)起請求,Django 隨即啟動或終止壓力腳本。
四、常見錯誤示例與調(diào)試技巧
錯誤 1:使用 import 直接運(yùn)行死循環(huán)
錯誤寫法:
from scripts.cpu_stress import stress
def start(request):
stress() # ? 會把 Django 線程卡死
原因:
壓力腳本死循環(huán) → Django 視圖無法返回 → 網(wǎng)站掛掉。
錯誤 2:subprocess 沒寫絕對路徑
錯誤寫法:
subprocess.Popen(["python", "cpu_stress.py"]) # ? 找不到腳本
正確寫法:
script = os.path.join(os.getcwd(), "scripts", "cpu_stress.py") subprocess.Popen([sys.executable, script])
錯誤 3:Windows 進(jìn)程無法 terminate
在 Windows 上,某些子進(jìn)程會繼續(xù)掛著,可以改為:
PROCESS.kill()
調(diào)試技巧:查看子進(jìn)程是否啟動
Linux / WSL:
ps aux | grep cpu_stress
Windows:
tasklist | findstr python
這類調(diào)試技巧在 AIOps 項目中非常常用。
五、生產(chǎn)環(huán)境高級技巧
1. 使用日志記錄子進(jìn)程輸出
subprocess.Popen(
[sys.executable, script],
stdout=open("out.log", "w"),
stderr=open("err.log", "w")
)
方便你排查模型腳本/壓力腳本的問題。
2. 給腳本加鎖,避免重復(fù)啟動
if PROCESS and PROCESS.poll() is None:
# 已經(jīng)在運(yùn)行中
防止用戶瘋狂點(diǎn)擊按鈕導(dǎo)致重復(fù)啟動多個壓力腳本。
3. 使用 Redis / 數(shù)據(jù)庫存儲子進(jìn)程 PID
生產(chǎn)環(huán)境推薦:
- Django View 啟動腳本
- 保存 PID 到 Redis
- 前端通過 PID 判斷腳本是否在運(yùn)行
4. 避免 SQLite 作為生產(chǎn)數(shù)據(jù)庫
你的前端壓力腳本會導(dǎo)致 SQLite 鎖表問題。
生產(chǎn)中建議使用:
- PostgreSQL(最常用)
- MySQL / MariaDB
SQLite 不適合頻繁寫入+多進(jìn)程并發(fā)。
六、背后原理與機(jī)制拓展
Django 本身不能跑長任務(wù)
Django 是典型的:
- 同步請求 → 同步響應(yīng)
- 一個請求不能占用長時間
所以它天生不適合:
- 死循環(huán)腳本
- 深度學(xué)習(xí)訓(xùn)練任務(wù)
- CPU 壓力測試腳本
- 視頻特征提取任務(wù)
這類任務(wù)應(yīng)該由:
- subprocess
- Celery
- 后臺 Worker
來完成。
為什么 subprocess 是最常用方案?
因?yàn)椋?/p>
- 獨(dú)立進(jìn)程,不影響 Django 主進(jìn)程
- 可以 kill / terminate
- 支持長時間運(yùn)行
- 支持日志
- 支持參數(shù)傳遞
- Windows / Linux 都能跑
它是 AIOps 平臺后臺運(yùn)行腳本的最基礎(chǔ)工具。
總結(jié)
文章介紹了 Django 調(diào)用外部 Python 腳本的三種方法,并通過完整的項目案例展示如何用 Django 前端按鈕啟動與停止 CPU 壓力腳本,同時補(bǔ)充了常見錯誤、調(diào)試技巧、高級實(shí)踐和背后原理。
到此這篇關(guān)于Django調(diào)用外部Python程序的文章就介紹到這了,更多相關(guān)Django調(diào)用外部Python程序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django框架orM與自定義SQL語句混合事務(wù)控制操作
這篇文章主要介紹了Django框架orM與自定義SQL語句混合事務(wù)控制操作,結(jié)合實(shí)例形式分析了同一個方法里面既有ORM又有自定義SQL 語句的情況下事務(wù)控制相關(guān)操作技巧,需要的朋友可以參考下2019-06-06
Python進(jìn)程的通信Queue、Pipe實(shí)例分析
這篇文章主要介紹了Python進(jìn)程的通信Queue、Pipe,結(jié)合實(shí)例形式分析了Python進(jìn)程通信Queue、Pipe基本概念、用法及操作注意事項,需要的朋友可以參考下2020-03-03
詳解Python實(shí)現(xiàn)按任意鍵繼續(xù)/退出的功能
在學(xué)Python時在總想實(shí)現(xiàn)一個按任意鍵繼續(xù)/退出的程序(受.bat毒害), 奈何一直沒有寫,今天抽時間寫出來了,下面分享給大家,有需要的可以參考借鑒。2016-08-08
Ubuntu 下 vim 搭建python 環(huán)境 配置
這篇文章主要介紹了Ubuntu 下 vim 搭建python環(huán)境配置,需要的朋友可以參考下2017-06-06

