起因
Pyinstaller 打包 django 項目,打包成 manage.exe 后用命令行 cmd
manage.exe runserver 0.0.0.0:8001 --noreload 來運行感覺很不方便。
希望能夠直接把命令行參數也打包進去,直接運行 exe 。我走了些彎路,但最終實現了。
彎路
我看到有人說 新建一個 main.py 在里面用 os.system :
import osos.system('manage.exe runserver 0.0.0.0:8001 --noreload')
看起來可行,在 manage.py 外包裹一層,但我嘗試以后失敗了,打包出的是一個這樣的結果:
運行無反應。沒去深究為啥失敗,畢竟對于打包我也不是太熟悉。
一種可行辦法
接下來是我自己的辦法。
其實也很簡單,找到 main 函數,修改參數列表。
我的 Django 的 manage.py
def main():os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'src.settings')try:from django.core.management import execute_from_command_lineexcept ImportError as exc:raise ImportError("Couldn't import Django. Are you sure it's installed and ""available on your PYTHONPATH environment variable? Did you ""forget to activate a virtual environment?") from excexecute_from_command_line(sys.argv)if __name__ == '__main__':main()
注意這句:
execute_from_command_line(sys.argv)
從函數名也能知道,這是一個實現從命令行執行的函數,傳入的正是 命令行參數列表 sys.argv
我們只要修改 sys.argv,就可以固定參數列表了。
但這里是有個小坑在的,如果是初學者可能會犯錯。
sys.argv 是參數列表,不是字符串,所以不可以直接把 ‘runserver 0.0.0.0:8001 --noreload’ 這串字符 append 進來,而要一個個來。
所以上面代碼可以改為:
) from excprint(sys.argv)sys.argv.append('runserver')sys.argv.append('0.0.0.0:8001')sys.argv.append('--noreload')print('增加參數后:')for a in sys.argv:print(a, end=' ')execute_from_command_line(sys.argv)
當然,寫成列表再 append 上也行的。
argv = ['runserver', '0.0.0.0:8001', '--noreload']sys.argv.append(argv)
然后 pyinstaller -w -F manage.py 就會生成 manage.exe 了。
不過打包成 exe ,后續可能還會遇到其它問題,比如運行起來后,資源找不到的問題,需要一一解決,manage.spec 我只能提醒一下。
我覺得 Django 似乎沒必要打包成 exe 。。。它用作網站欸,用 dos 界面運行就行了。
第二種辦法
如果不一定要生成 exe,只需要方便運行,其實 寫個 bat 腳本可能更方便一些。代碼都不用動。
直接加一個 bat 腳本運行 manage.py ,然后發送腳本快捷方式到桌面。
xxx.bat 腳本參考:
@echo offREM 這里加了一個臨時環境變量
set sslpath=D:\xxx\anaconda3-2020\Library\bin
set path=%sslpath%;%path%REM 此處用全局路徑會更合適,避免python升級影響。
python manage.py runserver 0.0.0.0:8001pause
這樣還會有個黑黑的 dos 界面,可能會被人不小關閉了。可以再寫個 vbs 調用剛才的 bat 腳本,隱藏 dos 界面:
set shell=wscript.createObject("wscript.shell")
run=shell.Run("xxx.bat, 0)
這樣的話,你想要看到進程,就只能再后臺看到一個 python 進程了。