Pyinstaller打包Django项目时子模块收集失败求助
问题场景
使用以下PyInstaller命令打包Django项目的manage.py:
pyinstaller --noconfirm --onedir --console --log-level "ERROR" --hidden-import "rest_framework.schemas" --hidden-import "django.contrib.gis.utils" --paths "C:/Users/a/Documents/GitHub/compute-local/backend/.env/Lib/site-packages" --additional-hooks-dir "C:/Users/a/Documents/GitHub/compute-local/backend/extra-hook" --hidden-import "djoser.urls" --paths "C:/Users/a/Documents/GitHub/compute-local/backend/.env/Lib/site-packages/djoser/urls" --paths "C:/Users/a/Documents/GitHub/compute-local/backend/.env/Lib/site-packages/rest_framework/schemas" --hidden-import "djoser" --hidden-import "rest_framework" "C:/Users/a/Documents/GitHub/compute-local/backend/manage.py"
执行后出现警告:
WARNING: 收集'djoser.urls'子模块失败,原因是导入'djoser.urls'时触发错误:django.core.exceptions.ImproperlyConfigured: 请求设置REST_FRAMEWORK,但未配置设置。您必须定义环境变量DJANGO_SETTINGS_MODULE或在访问设置前调用settings.configure()。
WARNING: 收集'rest_framework.schemas'子模块失败,原因是导入'rest_framework.schemas'时触发错误:django.core.exceptions.ImproperlyConfigured: 请求设置REST_FRAMEWORK,但未配置设置。您必须定义环境变量DJANGO_SETTINGS_MODULE或在访问设置前调用settings.configure()。
解决方案
1. 提前设置DJANGO_SETTINGS_MODULE环境变量
PyInstaller收集依赖时需要读取Django配置,先在终端中设置环境变量再执行打包命令:
- Windows CMD:
set DJANGO_SETTINGS_MODULE=backend.settings # 替换为你项目实际的settings模块路径 - Windows PowerShell:
$env:DJANGO_SETTINGS_MODULE="backend.settings"
设置完成后再执行你的PyInstaller打包命令。
2. 简化PyInstaller命令,移除冗余路径参数
命令中重复添加的子模块路径无需单独指定,只需保留虚拟环境的site-packages路径即可,修改后的命令示例:
pyinstaller --noconfirm --onedir --console --log-level "ERROR" ^ --hidden-import "rest_framework.schemas" ^ --hidden-import "django.contrib.gis.utils" ^ --hidden-import "djoser" --hidden-import "djoser.urls" ^ --hidden-import "rest_framework" ^ --paths "C:/Users/a/Documents/GitHub/compute-local/backend/.env/Lib/site-packages" ^ --additional-hooks-dir "C:/Users/a/Documents/GitHub/compute-local/backend/extra-hook" ^ "C:/Users/a/Documents/GitHub/compute-local/backend/manage.py"
3. 自定义PyInstaller钩子初始化Django配置
在你的additional-hooks-dir目录下创建hook-django.py文件,内容如下:
import os import django from django.conf import settings if not settings.configured: # 替换为你项目的settings模块路径 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') django.setup()
该钩子会在PyInstaller收集依赖前初始化Django配置,避免导入模块时的配置错误。
原理说明
这些警告的核心原因是:PyInstaller扫描依赖时,导入djoser、rest_framework的相关模块需要读取Django配置,但此时未设置DJANGO_SETTINGS_MODULE环境变量,导致Django无法完成初始化。通过上述三种方式提前完成Django配置的初始化,即可解决该问题。
内容的提问来源于stack exchange,提问作者PolarBear10

