进阶指南:如何编写可重用程序
这篇进阶指南从 Tutorial 7 结尾的地方继续讲起。我们将会把我们的 Web-poll 放进一个独立的 Python 包中,以便你在新的项目中重用它或将它与他人分享。
如果你尚未完成教程 1-7,我们推荐你先浏览一遍教程,这样你的样例工程会和下面的一致。
可重用性很重要
设计,构建,测试以及维护一个 web 应用要做很多的工作。很多 Python 以及 Django 项目都有一些常见问题。如果我们能保存并利用这些重复的工作岂不是更好?
可重用性是Python的生存方式。 Python软件包索引(PyPI) 有很多可以在你自己的Python程序中使用的软件包。查看 Django Packages 以了解您可以整合到项目中的现有可重用应用。Django本身也只是一个Python包。这意味着您可以将现有的Python包或Django应用组合到您自己的Web项目中。您只需编写您项目独一无二的部分。
Let's say you were starting a new project that needed a polls app like the onewe've been working on. How do you make this app reusable? Luckily, you're wellon the way already. In Tutorial 1, we saw how wecould decouple polls from the project-level URLconf using an include
.In this tutorial, we'll take further steps to make the app easy to use in newprojects and ready to publish for others to install and use.
包?应用?
一个 package 提供了一组关联的 Python 代码的简单复用方式。一个包(“模块”)包含了一个或多个 Python 代码文件。
一个包通过 import foo.bar
或 from foo import bar
的形式导入。一个目录(例如 polls
)要成为一个包,它必须包含一个特定的文件 init.py
,即便这个文件是空的。
Django 应用 仅仅是专用于 Django 项目的 Python 包。应用会按照 Django 约定,创建好 models
, tests
, urls
, 以及 views
等子模块。
稍后,我们将解释术语 打包 ——为了方便其它人安装 Python 包的处理流程。我知道,这可能会使你感到一点点迷惑。
你的项目和可复用应用
通过前面的教程,我们的工程应该看起来像这样:
- mysite/
- manage.py
- mysite/
- __init__.py
- settings.py
- urls.py
- wsgi.py
- polls/
- __init__.py
- admin.py
- migrations/
- __init__.py
- 0001_initial.py
- models.py
- static/
- polls/
- images/
- background.gif
- style.css
- templates/
- polls/
- detail.html
- index.html
- results.html
- tests.py
- urls.py
- views.py
- templates/
- admin/
- base_site.html
1
目录 polls
现在可以被拷贝至一个新的 Django 工程,且立刻被复用。不过现在还不是发布它的时候。为了这样做,我们需要打包这个应用,便于其他人安装它。
安装必须环境
目前,打包 Python 程序需要工具,有许多工具可以完成此项工作。在此教程中,我们将使用 setuptools 来打包我们的程序。这是推荐的打包工具(与 发布
分支合并)。我们仍旧使用 pip 来安装和卸载这个工具。现在,你需要安装这两个包。如果你需要帮助,你可以参考 如何通过 pip 安装 Django,你可以通过相同的方式安装 setuptools
。
打包你的应用
Python 的 打包 将以一种特殊的格式组织你的应用,意在方便安装和使用这个应用。Django 本身就被打包成类似的形式。对于一个小应用,例如 polls,这不会太难。
- 首先,在你的 Django 项目目录外创建一个名为
django-polls
的文件夹,用于盛放polls
。
为你的应用选择一个名字
当为你的包选一个名字时,避免使用像 PyPI 这样已存在的包名,否则会导致冲突。当你创建你的发布包时,可以在模块名前增加 django-
前缀,这是一个很常用也很有用的避免包名冲突的方法。同时也有助于他人在寻找 Django 应用时确认你的 app 是 Django 独有的。
应用标签(指用点分隔的包名的最后一部分)在 INSTALLED_APPS
中 必须 是独一无二的。避免使用任何与 Django contrib packages 文档中相同的标签名,比如 auth
,admin
,messages
。
将
polls
目录移入django-polls
目录。创建一个名为
django-polls/README.rst
的文件,包含以下内容:
- =====
- Polls
- =====
- 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 "polls" to your INSTALLED_APPS setting like this::
- INSTALLED_APPS = [
- ...
- 'polls',
- ]
- 2. Include the polls URLconf in your project urls.py like this::
- path('polls/', include('polls.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/polls/ to participate in the poll.
创建一个
django-polls/LICENSE
文件。选择一个非本教程使用的授权协议,但是要足以说明发布代码没有授权证书是 不可能的 。Django 和很多兼容 Django 的应用是以 BSD 授权协议发布的;不过,你可以自己选择一个授权协议。只要确定你选择的协议能够限制未来会使用你的代码的人。下一步我们将创建
setup.py
用于说明如何构建和安装应用的细节。关于此文件的完整介绍超出了此教程的范围,但是 setuptools docs 有详细的介绍。创建文件django-polls/setup.py
包含以下内容:
- import os
- from setuptools import find_packages, setup
- 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='django-polls',
- version='0.1',
- packages=find_packages(),
- include_package_data=True,
- license='BSD License', # example license
- description='A simple Django app to conduct Web-based polls.',
- long_description=README,
- url='https://www.example.com/',
- author='Your Name',
- author_email='yourname@example.com',
- classifiers=[
- 'Environment :: Web Environment',
- 'Framework :: Django',
- 'Framework :: Django :: X.Y', # replace "X.Y" as appropriate
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: BSD License', # example license
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
- 'Topic :: Internet :: WWW/HTTP',
- 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
- ],
- )
- 默认包中只包含 Python 模块和包。为了包含额外文件,我们需要创建一个名为
MANIFEST.in
的文件。上一步中关于 setuptools 的文档详细介绍了这个文件。为了包含模板、README.rst
和我们的LICENSE
文件,创建文件django-polls/MANIFEST.in
包含以下内容:
- include LICENSE
- include README.rst
- recursive-include polls/static *
- recursive-include polls/templates *
- 在应用中包含详细文档是可选的,但我们推荐你这样做。创建一个空目录
django-polls/docs
用于未来编写文档。额外添加一行至django-polls/MANIFEST.in
- recursive-include docs *
注意,现在 docs
目录不会被加入你的应用包,除非你往这个目录加几个文件。许多 Django 应用也提供他们的在线文档通过类似 readthedocs.org 这样的网站。
- 试着构建你自己的应用包通过
ptyhon setup.py sdist
(在django-polls
的目录并构建你自己的应用包,目录内)。这将创建一个名为
distdjango-polls-0.1.tar.gz
。
For more information on packaging, see Python's Tutorial on Packaging andDistributing Projects.
使用你自己的包名
由于我们把 polls
目录移出了项目,所以它无法工作了。我们现在要通过安装我们的新 django-polls
应用来修复这个问题。
作为用户库安装
以下步骤将 django-polls
以用户库的形式安装。与安装整个系统的软件包相比,用户安装具有许多优点,例如可在没有管理员访问权的系统上使用,以及防止应用包影响系统服务和其他用户。
注意,用户安装仍然会影响以这个用户身份运行的系统工具,所以 virtualenv
是一个更强大的解决方案(如下所示)。
- 为了安装这个包,使用 pip (你早已 安装 pip, 对吗?):
- pip install --user django-polls/dist/django-polls-0.1.tar.gz
幸运的话,你的 Django 项目应该再一次正确运行。启动服务器确认这一点。
通过 pip 卸载包:
- pip uninstall django-polls
发布你的应用
现在,你已经对 django-polls
完成了打包和测试,准备好向世界分享它!如果这不是一个例子应用,你现在就可以这样做。
- 通过邮件将你的包发送给朋友。
- 将这个包上传至你的网站。
- Post the package on a public repository, such as the Python Package Index(PyPI). packaging.python.org has a goodtutorialfor doing this.
通过 virtualenv 安装 Python 包
早些时候,我们以用户库的形式安装了投票应用。这样做有一些缺点。
- 修改用户库会影响你系统上的其他 Python 软件。
- 你将不能运行此包的多个版本(或者其它用有相同包名的包)。
一般来说,这些状况只在你同时运行多个 Django 项目时出现。当这个问题出现时,最好的解决办法是使用 virtualenv。这个工具允许你同时运行多个相互独立的Python环境,每个环境都有各自库和应用包命名空间的拷贝。