在Windows上让Django服务开机自启动,最直接的方法是创建一个Windows服务。这比用计划任务更稳定,能更好地管理服务的生命周期(启动、停止、重启)。下面是一个使用pywin32库的完整方案。
核心思路:编写一个Python脚本,将你的Django应用(通过manage.py runserver或ASGI/WSGI服务器)包装成标准的Windows服务。
第一步:安装必要库
你需要安装pywin32。建议在项目虚拟环境中安装:
pip install pywin32
第二步:创建服务脚本
创建一个新文件,例如django_windows_service.py。以下是完整代码,你需要根据你的项目路径修改DJANGO_PROJECT_PATH和DJANGO_SETTINGS_MODULE。
# django_windows_service.py
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import sys
import os
import subprocess
import threading
import time
# 配置你的Django项目路径和设置
DJANGO_PROJECT_PATH = r'C:\path\to\your\django_project' # 修改为你的项目绝对路径
DJANGO_SETTINGS_MODULE = 'your_project.settings' # 修改为你的settings模块
PORT = 8000 # 服务监听的端口
class DjangoService(win32serviceutil.ServiceFramework):
"""Windows服务类"""
_svc_name_ = 'DjangoAppService' # 服务名称,在服务管理器中显示
_svc_display_name_ = 'Django Application Service' # 显示名称
_svc_description_ = '运行Django开发服务器的Windows服务' # 服务描述
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.process = None
socket.setdefaulttimeout(60)
def SvcStop(self):
"""停止服务时调用"""
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
if self.process:
self.process.terminate()
self.process.wait()
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
"""服务主运行逻辑"""
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYSERVICE_STARTED,
(self._svc_name_, '')
)
self.main()
def main(self):
"""启动Django服务器"""
# 切换到项目目录
os.chdir(DJANGO_PROJECT_PATH)
# 设置环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', DJANGO_SETTINGS_MODULE)
# 构建命令:使用python解释器运行manage.py runserver
# 注意:这里使用sys.executable确保使用当前Python环境
cmd = [
sys.executable,
'manage.py',
'runserver',
f'0.0.0.0:{PORT}',
'--noreload' # 必须禁用自动重载,否则服务无法正常运行
]
try:
self.process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
# 简单日志输出(实际生产可配置更完善的日志)
while True:
output = self.process.stdout.readline()
if output:
servicemanager.LogInfoMsg(output.strip())
if self.process.poll() is not None:
break
time.sleep(0.1)
except Exception as e:
servicemanager.LogErrorMsg(f'服务启动失败: {str(e)}')
self.SvcStop()
if __name__ == '__main__':
if len(sys.argv) == 1:
# 注册服务
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(DjangoService)
servicemanager.StartServiceCtrlDispatcher()
else:
# 处理命令行参数(安装、启动、停止等)
win32serviceutil.HandleCommandLine(DjangoService)
第三步:安装和管理服务
用管理员权限打开命令提示符(CMD)或PowerShell,执行以下操作:
- 安装服务:
python django_windows_service.py install
- 启动服务:
python django_windows_service.py start
- 停止服务:
python django_windows_service.py stop
- 卸载服务:
python django_windows_service.py remove
重要说明
- 生产环境警告:
runserver仅用于开发。生产环境请改用waitress、gunicorn(配合WSL)或部署到IIS。
- 路径问题:确保
DJANGO_PROJECT_PATH是绝对路径,且Python环境包含所有项目依赖。
- 端口冲突:如果端口被占用,服务会启动失败。
- 服务依赖:如需设置服务依赖(如先启动MySQL),可在服务管理器中配置。
替代方案(简单但不够健壮)
如果不想创建Windows服务,可以用任务计划程序:
- 创建基本任务,触发器设为“计算机启动时”。
- 操作为“启动程序”,程序填
python.exe,参数填manage.py runserver 0.0.0.0:8000。
- 起始于填你的项目路径。
不过任务计划程序启动的应用在用户注销后会停止,且服务管理功能较弱。
总结:用pywin32创建Windows服务是最接近Tomcat方式的做法。