Pyinstaller打包Django项目(耗时两天 踩坑无数 记录一下)

背景

朋友开了个小医疗公司,平时给客户发货开出货单使用的是祖上传下来的据说花了三百大洋买的一个小软件,扯淡的是每次开完出货单,复杂流程搞完之后去仓库取货,发现仓库货用完了,想着帮忙给他搞一个小程序可以管理仓库,并且由于他本人极怕麻烦,不愿意安装任何额外软件(一个小小的MySQL都不行),所以开发完成后使用了Pyinstaller将程序打包成exe以保证无需环境影响可双击直接运行,并且本程序所有数据存储均使用本地txt文件来保存…

开始打包

开发过程不多叙述,成品欢迎参观 本人Gitee陋室

第一步:

本人目录格式:
在这里插入图片描述
首先进入到主目录,也就是manage.py文件所在的目录,执行pyi-makespec -D manage.py来生成manage.spec文件,
我是直接在pycharm下的终端输入的,本地cmd同样可行(务必先进入到项目依赖的虚拟环境
在这里插入图片描述

第二步:

如果啥也不管直接pyinstaller manage.spec虽然可以打包成功,但是你会发现根本运行不起来,各种报错。
这里我们修改刚刚第一步生成的spec文件, 填充hiddenimports的值为settings里的INSTALLED_APPS,如图所示:
注意:我们不但引入了所有的app,并且还引入了他们各自的urls文件,如果在项目中你有自定义的tags,也要一并引入(就像我自定义了一个helpp在account下,那么我的spec文件中也就出现了APPs.account.templatetags.helpp)

准备就绪,打包: pyinstaller manage.spec
settings文件内容
spec文件内容

第三步:

关键的一步来了,就在这出现了N个大坑,打包完成后,cd 到dist/manage/,运行manage.exe runserver 开始进坑…

坑一 No module named 'myck.settings'

不知道你们会不会遇到这个问题,我被这个问题困扰了一个下午,网上并没有找到跟我一样类似的问题,大家都在说出现 No module named 'xxx’直接在spec文件里添加 hiddenimports 就行了,然而对于这个问题,并没有用。
在这里插入图片描述
解决办法:直接copy asgi.py settings.py urls.py wsgi.py四个文件到dist/manage/myck/下粘贴即可。

在这里插入图片描述
在这里插入图片描述

坑二 静态界面缺失(小水坑)

运行成功,发现界面出现错误:
在这里插入图片描述
放轻松,只需将所有静态文件(个人习惯,我所有App的静态界面都在统一的一个文件夹内templates,根据提示,将该文件夹放在打包后生成的dist/manage/下即可)。

坑三 CSS, JS文件缺失 (印第安人捕兽坑)

在第二个坑的时候你想到了既然静态文件缺失可以这么解决,那么CSS和JS文件同样也行,没错,出现CSS,JS文件缺失确实需要按照坑二的方法做一遍,但这并没有解决问题,因为我们还需要一步:修改主urls.py文件,也就是跟settings.py文件同目录的那个,我们添加如下代码:

# 打包时使用
from django.conf.urls import static
from myck import settings
urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

settings.py文件中的STATIC_URL和STATIC_ROOT变量内容如下
在这里插入图片描述

就像这样(请忽略我的pinyin命名法,实在是不想用index了)
在这里插入图片描述
坑四 because its MIME type (‘text/plain‘) is not executable (深渊巨坑)
在这里插入图片描述
说实话这个问题快给我整疯了,我甚至把每个静态界面的<script>标签全都加上了application/javascript并没有什么用,万万没想到,问题竟然会出在注册表上, 以下为大佬原回答:

还有一种情况可能是Windows系统上不知道什么时候破坏了注册表,把扩展名为js的文件类型注册为 ‘text/plain’, 应该为’application/javascript’。
要解决这个问题,请在 Django项目 setting.py 中 末尾添加如下代码,强制Django使用’application/javascript’ 作为 js文件类型
第三种解决方法:

#在settings.py末尾加入
import mimetypes
mimetypes.add_type('text/css', '.css')
mimetypes.add_type('application/javascript', '.js')

大佬回答链接:https://blog.csdn.net/shenbossed/article/details/111773588

坑五 RuntimeError: Script runserver does not exist. (凑个数吧, ‘四’不好听)
所有问题全部解决,兴奋的去运行,发现报错RuntimeError: Script runserver does not exist.
解决办法:只需在命令末尾加上 --noreload即可
完整命令:cd 进入到dist/manage/后执行 manage.exe runserver 1627 --noreload
(1627为端口号 可自定义修改)
在这里插入图片描述

新增函数一键运行Django

在保证不会重复运行服务的情况下自动打开默认浏览器并跳转到指定界面:

import os
import sys
import webbrowser
import psutil

BASE_PATH = os.path.abspath('.')
# 重复点击开始即关闭原来服务重新打开
os.system('TASKKILL /F /IM manage.exe')


def run_main():
    sys.path.append("libs")
    url = 'http://127.0.0.1:1627'
    webbrowser.open_new(url)
    main = BASE_PATH + "/manage.exe runserver 1627 --noreload"
    print('--------------------------')
    print('系统已运行,可关闭此终端.')
    print('--------------------------')
    os.system(main)


run_main()

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值