主要分为部分
编写可以直接运行的manage.py文件,使你的工程能直接运行起来
编写打包程序--导入所有需要用到的py文件
编写打包程序--复制所有的静态文件,包括html相关、日志、数据库文件等(这一步可以打包后,手动黏贴到打包目录就行)
首先看第一点,这个参考django的文档
#manage.py def run_django(): import os os.environ.setdefault( "DJANGO_SETTINGS_MODULE","LabelIssuance2.win_settings" ) # 导入django包 from django.core.wsgi import get_wsgi_application from django.core.servers.basehttp import run application = get_wsgi_application() run( "127.0.0.1",8000,application )
创建一个新的py文件,例如start.py,导入manage.py后,调用此方法,能正常开启django程序,说明第一步没有问题了。
第二点,导入所有用的python程序
这里主要包含了:
>>整个django包(因为django内部有些程序会遍历django包,如果不全部导入,会出现找不到的情况)
>>使用的第三方python插件包(即位于X:\Python27\Lib\site-packages文件夹下的内容)
>>django工程代码本身
我是写了简单的循环递归来获取所有的py文件的
def get_third_module( path,key ): """ @attention: 获取第三方的py文件集合 """ temp_list = [] if os.path.isdir( path ): path_list = os.listdir( path ) if "__init__.py" in path_list: for item in os.listdir( path ): path1 = os.path.join( path,item ) temp_list.extend( get_third_module( path1,key ) ) else: if path.endswith( ".py" ) and ( not path.endswith( "__init__.py" ) ): temp = re.findall( r"(%s.*).py" % key,path, ) temp_list.append( ( re.sub( r"\\+",".",temp[0] ) ) ) return temp_list def get_local_module( path,key ): """ @attention: 获取工程的代码py文件 """ temp_list = [] if os.path.isdir( path ): path_list = os.listdir( path ) if "__init__.py" in path_list: for item in os.listdir( path ): path1 = os.path.join( path,item ) temp_list.extend( get_local_module( path1,key ) ) else: if path.endswith( ".py" ) and ( not path.endswith( "__init__.py" ) ): temp = re.findall( r"%s.(.*).py" % key,path, ) temp_list.append( ( re.sub( r"\\+",".",temp[0] ) ) ) return temp_list def include_module(): """ @attention: 需要导入的模块,分为第三方插件+站点本身 """ res_list = [] python_path = "C:\\Python27\\Lib\\site-packages" third_list = ["django", "djangorestframework-2.3.13-py2.7.egg\\rest_framework", "serial"] for name in third_list: key = os.path.split( name )[-1] path = os.path.join( python_path,name ) res_list.extend( get_third_module( path,key ) ) path = os.getcwd() key = os.path.split( path )[-1] res_list.extend( get_local_module( path,key ) ) return res_list
注意获取工程本身时,最外层由于没有__init__.py文件,会导致manage.py文件,无法获取到,所以手动加一个__init__.py文件在最外层
接着复制相关静态文件
要求格式是一个二维数组,每项的格式为: (打包后目录,[复制的文件路径集合]);
例如:['static/image',[1.png,2.png]]
会在打包后文件夹生成一个static文件夹,static文件夹生成一个image文件夹,然后把1.png,2.png复制到里面,这里我们需要写程序实现把文件放的目录和工程一致即可
打包后目录默认是打包文件的起始目录,文件路径集合要求是最好是全路径
def get_static_file( path,key,reslist ): """ @attention: 打包静态文件 """ file_list = [] for item in os.listdir( path ): new_path = os.path.join( path,item ) if os.path.isdir(new_path): new_key = os.path.join( key,os.path.split( new_path )[-1] ) get_static_file( new_path,new_key,reslist ) else: file_list.append( new_path ) if file_list: reslist.append( [key,file_list] ) def get_data_file(): path = u"D:\\work\\svn_tianjing\\LabelIssuance2\\static" key = os.path.split( path )[-1] reslist = [] get_static_file( path,key,reslist ) base = ( '',['runserver.bat','database','package.bat','cng.ico','DLLDES.dll'] ) reslist.append( base ) return reslist
PS:官网大部分用的glob,小弟觉得解决不了,求更简单写法 = =!
最后是打包程序
opts = { "py2exe":{"includes":include_module()} } setup( options=opts, windows=[{"script":"start.py","icon_resources": [( 1,"cng.ico" )]}], data_files=get_data_file() , ) setup( options=opts, windows=[{"script":"start.py","icon_resources": [( 1,"cng.ico" )]}], data_files=get_data_file() , )
写两次setup是因为不知道为什么,启动exe的图标显示不出来,听某高人指点,说写两次就行了,尝试后,还真行!!求过客说明原因~