Django 项目打包可执行文件

Django 项目打包可执行文件

坑 1:Django 依赖项

pyinstaller

还有用py2app的,放弃了
https://github.com/kevinlondon/django-py2app-demo

坑 2:pandas 依赖项

并且解决了引用了肥大无用的 mkl 动态库。

总结如下

1
conda create -n exe python=3
2
activate exe
3
conda install -c conda-forge pandas
4
pip install pyinstaller
5
pip isntall -r requirements.txt
6
pyi-makespec -D manage.py -n WordReview_D  
7
pyinstaller --clean --noconfirm WordReview_D.spec
1
# -*- mode: python ; coding: utf-8 -*-
2
3
block_cipher = None
4
5
a = Analysis(['manage.py'],
6
             pathex=['/Users/benature/Documents/Coding/Web/TG_word'],
7
             binaries=[],
8
             datas=[
9
                 ('/Users/benature/Documents/Coding/Web/TG_word/static','staticsfile'), 
10
                ('/Users/benature/Documents/Coding/Web/TG_word/templates', 'templates'),
11
                ('/Users/benature/Documents/Coding/Web/TG_word/apps', 'apps'),
12
                #('/Users/benature/Documents/Coding/Web/TG_word/pypi/pypugjs', 'pypugjs'),
13
                
14
             ],
15
             hiddenimports=[
16
                'pkg_resources.py2_warn',
17
                'django.contrib.admin',
18
                'django.contrib.auth',
19
                'django.contrib.contenttypes',
20
                'django.contrib.sessions',
21
                'django.contrib.messages',
22
                'django.contrib.staticfiles',
23
                'sass_processor',
24
                'sass_processor.apps',
25
                'sass_processor.finders',
26
                'pypugjs',
27
                'pypugjs.ext.django',
28
                'pypugjs.ext.django.templatetags',
29
                'pandas.read_excel',
30
                'dateutil',
31
                'six',
32
                'xlrd',
33
             ],
34
             hookspath=[],
35
             runtime_hooks=[],
36
             excludes=[
37
                'pymysql',
38
                'mysqlclient',
39
             ],
40
             win_no_prefer_redirects=False,
41
             win_private_assemblies=False,
42
             cipher=block_cipher,
43
             noarchive=False)
44
45
def get_pandas_path():
46
    import pandas
47
    pandas_path = pandas.__path__[0]
48
    return pandas_path
49
dict_tree = Tree(get_pandas_path(), prefix='pandas', excludes=["*.pyc"])
50
a.datas += dict_tree
51
a.binaries = filter(lambda x: 'pandas' not in x[0], a.binaries)
52
53
pyz = PYZ(a.pure, a.zipped_data,
54
             cipher=block_cipher)
55
56
Key = ['mkl','libopenblas']
57
#Key = ['mkl', 'libopenblas', 'liblapack', 'libblas', 'libcblas']
58
def remove_from_list(input, keys):
59
    outlist = []
60
    for item in input:
61
        name, _, _ = item
62
        flag = 0
63
        for key_word in keys:
64
            if name.find(key_word) > -1:
65
                flag = 1
66
        if flag != 1:
67
            outlist.append(item)
68
    return outlist
69
a.binaries = remove_from_list(a.binaries, Key)
70
71
exe = EXE(pyz,
72
          a.scripts,
73
          [],
74
          exclude_binaries=True,
75
          name='WordReview_D',
76
          debug=False,
77
          bootloader_ignore_signals=False,
78
          strip=False,
79
          upx=True,
80
          console=True )
81
coll = COLLECT(exe,
82
               a.binaries,
83
               a.zipfiles,
84
               a.datas,
85
               strip=False,
86
               upx=True,
87
               upx_exclude=[],
88
               name='WordReview_D')

附注:执行 migrate 后可以删除libblas.3.dylib, libcblas.3.dylib, liblapack.3.dylib。大概率不影响正常使用。