如何用PyInstaller将Django+WebSocket打字游戏打包为可独立运行的exe
解决Django+WebSocket打字游戏打包为独立.exe的问题
问题根源
你之前的runner.py通过调用系统python命令启动Django服务,目标机没有Python环境、也没有项目文件,自然无法启动服务。需要将Python解释器、Django依赖、整个项目文件打包到单个.exe中。
步骤1:修改启动逻辑(替换原runner.py)
不要通过subprocess调用外部命令,直接在代码中启动Django服务,同时避免阻塞主线程:
import os import sys import time import threading import django from django.core.management import execute_from_command_line # 配置Django环境,替换为你的项目名 PROJECT_NAME = "typing_game" # 改成你的实际项目名称 os.environ.setdefault('DJANGO_SETTINGS_MODULE', f'{PROJECT_NAME}.settings') # 处理PyInstaller打包后的路径问题 if hasattr(sys, '_MEIPASS'): # 打包后,项目文件会放在临时目录sys._MEIPASS下 BASE_DIR = os.path.join(sys._MEIPASS, PROJECT_NAME) os.chdir(BASE_DIR) django.setup() # 后台启动Django服务器 def start_server(): execute_from_command_line(['manage.py', 'runserver', '127.0.0.1:8000', '--noreload']) server_thread = threading.Thread(target=start_server) server_thread.daemon = True server_thread.start() # 等待服务启动(可根据实际情况调整时长) time.sleep(3) # 打开默认浏览器,兼容不同Windows设备 if sys.platform == 'win32': os.startfile('http://localhost:8000')
步骤2:调整Django项目路径配置
修改项目的settings.py,确保打包后能正确读取模板、静态文件:
import sys import os # 基础路径配置 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 适配PyInstaller打包环境 if hasattr(sys, '_MEIPASS'): BASE_DIR = os.path.join(sys._MEIPASS, 'typing_game') # 替换为你的项目名 # 模板路径 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, # 其他配置... }, ] # 静态文件路径 STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
如果使用了WebSocket(比如Channels),确保asgi.py也正确配置路径,并且依赖被包含。
步骤3:用PyInstaller打包(使用.spec文件)
- 生成初始.spec文件:
pyinstaller --onefile --noconsole runner.py
- 编辑生成的
runner.spec文件,添加项目文件和隐藏依赖:
# 修改pathex为你的项目根目录 pathex=['C:/path/to/your/project/root'] # 替换成实际路径 # 添加需要打包的项目文件(根据你的项目结构调整) datas = [ ('typing_game/templates', 'typing_game/templates'), ('typing_game/static', 'typing_game/static'), ('typing_game/apps', 'typing_game/apps'), ('typing_game/settings.py', 'typing_game'), ('typing_game/urls.py', 'typing_game'), ('typing_game/asgi.py', 'typing_game'), # WebSocket需要ASGI ('manage.py', '.'), ] # 添加Django和WebSocket相关的隐藏依赖 hiddenimports = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'channels', # 如果用了Channels 'channels.routing', 'channels.layers', 'typing_game.apps.your_app_name', # 替换成你的APP名称 ]
- 用.spec文件重新打包:
pyinstaller runner.spec
测试验证
将dist目录下的.exe文件复制到无Python环境的Windows设备,运行后会自动启动Django服务并打开浏览器,WebSocket功能也能正常工作。
内容的提问来源于stack exchange,提问作者Acno_Sama
相关产品推荐
相关产品推荐

