有时候,我们需要将自己写的app分发(dist)给同事,分享给朋友,或者在互联网上发布,这都需要打包、分发我们的app。
Django的子系统重用是基于app级别的。也就是一个项目可以包含多个互相独立的app,不同项目之间没有关系。但是,一个app可以属于多个项目,可以在任何地点、任何时间和任何项目中被重用。需要将该app运行时所必须的全部文件、资源、配置、数据等等都封装在一个整体内。
打包工具:setuptools、pip。一般情况下安装Python时已自带安装了。
官方文档:https://docs.djangoproject.com/zh-hans/2.0/intro/reusable-apps/
打包的本质,就是封装你的源代码和文件成为一种新的数据包装格式,有利于传输、分发和安装。在Django中打包一个app总体上看分三大步:装包—>编写setup.py—>打包。
创建一个说明文档django-polls/README.rst,写入下面的内容:
=====
base_system
=====
Polls is a simple Django app to conduct Web-based polls. For each
question, visitors can choose between a fixed number of answers.
Detailed documentation is in the "docs" directory.
Quick start
-----------
1. Add "base_system" to your INSTALLED_APPS setting like this::
INSTALLED_APPS = [
...
'base_system',
]
2. Include the polls URLconf in your project urls.py like this::
path('base-system/', include('base_system.urls')),
3. Run `python manage.py migrate` to create the polls models.
4. Start the development server and visit http://127.0.0.1:8000/admin/
to create a poll (you'll need the Admin app enabled).
5. Visit http://127.0.0.1:8000/base-system/ to participate in the base_system.
这其实是一个纯文本文件,内容和格式完全自由,但核心要点是注明你的app功能和简单的使用方法
创建一个LICENSE版权申明文件。大多数Django相关的app都基于BSD版权
Copyright (c) The Wharton School and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of DRF Renderer XLSX nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
默认情况下,只有Python的模块和包会被打包进我们的app内。为了包含一些其它的文件,比如静态文件、templates模板等非Python语言编写的文件,需要创建一个MANIFEST.in文件,并写入下面的内容:
include LICENSE
include README.rst
recursive-include polls/static *
recursive-include polls/templates *
该步骤可选,但是强烈推荐将详细的说明文档一起打包。创建一个空的目录docs,用于放置app相关的所有文档。同时不要忘了,在MANIFEST.in文件内加入一行 “recursive-include docs *”。需要注意的是,如果docs目录是空的,那么它不会被打包进去。
创建一个django-polls/setup.py文件,包含了编译和安装app的配置细节。这种配置脚本的具体语法,请前往setuptools的官方文档获取详细的教程。下面是一个范例,大多数情况下,你在此基础上改改就可以了:
import os
from setuptools import setup, find_packages
# with open("README.md") as f:
# long_description = f.read()
# with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
# README = readme.read()
# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
setup(
name="base_system",
version='0.0.4',
description="Medical system base data",
keywords='base_system',
# long_description=README,
long_description_content_type="text/markdown",
author='zcjwin',
author_email='[email protected]',
url="https://devcloud.huaweicloud.com/",
include_package_data=True,
# 你要安装的包,通过 setuptools.find_packages 找到当前目录下有哪些包
packages=find_packages(include=('base_system',)),
zip_safe=False,
# 表明当前模块依赖哪些包,若环境中没有,则会从pypi中下载安装
install_requires=[
'Django>=2.0',
'djangorestframework>=3.7.0',
'xlrd2>=1.3.4',
'pyDes>=2.0.1',
'drf-excel>=2.1.0',
],
# 仅在测试时需要使用的依赖,在正常发布的代码中是没有用的。
# 在执行python setup.py test时,可以自动安装这三个库,确保测试的正常运行。
tests_require=[
'coveralls>=1.11.1',
'django-allauth==0.50.0',
'djangorestframework-simplejwt==4.6.0',
'responses==0.12.1',
'unittest-xml-reporting==3.0.4',
],
test_suite='runtests.runtests',
setup_requires=["setuptools_scm"],
# use_scm_version=True, # 是否使用pip install git+https://的方式安装
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3 :: Only",
"Framework :: Django",
"Framework :: Django :: 2",
"Framework :: Django :: 3",
"Framework :: Django :: 4",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
],
)
在setup.py同级目录内,运行 “python setup.py sdist” 命令。这将会创建一个dist目录,并生成base-system-0.0.4.tar.gz打包文件。
~/.pypirc 配置 PyPI 访问地址和账号
[distutils]
index-servers = pypi
[pypi]
username:xxx
password:xxx
# 信息注册
$ python setup.py register
# 上传源码包
$ python setup.py upload
可以安装工具把打好的包上传到PyPI上面
pip install twine
python setup.py sdist
twine upload dist/base-system-0.0.4.tar.gz
python setup.py sdist bdist_wheel && twine upload dist/*
实际使用时,我们只需要拿着base-system-0.0.4.tar.gz这个文件就可以了。
在安装包的时候,最好是以个人用户的身份安装,而不是全系统范围的身份。这样可以有效减少给别的用户带去的影响或被别的用户影响。当然,最好的方式是在virtualenv环境,这种类似隔离的沙盒环境中使用(此时,不需要–user选项)。
pip install base-system-0.0.4.tar.gz
安装成功后,在当前Django项目的INSTALLED_APPS设置中注册base_system,然后启动服务器,就可以使用这个app了。这个过程中,你可能还需要配置urls、makemigrations、migrate、创建数据实例等动作。
pip uninstall base_system