进阶指南:如何编写可重用程序Link to this heading

这篇进阶指南从 教程 7 结尾的地方继续讲起。我们将会把我们的网络投票应用放进一个独立的 Python 包中,以便你在新的项目中重用它或将它与他人分享。

如果你尚未完成教程 1-7,我们推荐你先浏览一遍教程,这样你的样例工程会和下面的一致。

可重用性很重要Link to this heading

设计,构建,测试以及维护一个 web 应用要做很多的工作。很多 Python 以及 Django 项目都有一些常见问题。如果我们能保存并利用这些重复的工作岂不是更好?

可重用性是 Python 的根本。The Python Package Index (PyPI) 有许大量的包,都可被用在你自己的 Python 项目中。同样可以在 Django Packages 中查找已发布的可重用应用,也可将其引入到你的项目中。Django 本身也是一个 Python 包,也就是说你可以将已有的 Python 包或 Django 应用并入你的项目。你只需要编写属于你的那部分即可。

假设你现在创建了一个新的项目,并且需要一个类似我们之前做的投票应用。你该如何复用这个应用呢?庆幸的是,其实你已经知道了一些。在 教程 1,我们使用过 include 从项目级别的 URLconf 分割出 polls。在本教程中,我们将进一步使这个应用易用于新的项目中,并发布给其他人安装使用。

你的项目和可复用应用Link to this heading

通过前面的教程,我们的工程应该看起来像这样:

Code
mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py
    polls/
        __init__.py
        admin.py
        apps.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

你在 教程 7 中创建了 mysite/templates,在 教程 3 中创建了 polls/templates。现在也许更清楚为什么我们选择为项目和应用程序设置单独的模板目录:所有属于 polls 应用程序的部分都在 polls 中。这使得应用程序自成一体,更容易放到一个新项目中。

目录 polls 现在可以被拷贝至一个新的 Django 工程,且立刻被复用。不过现在还不是发布它的时候。为了这样做,我们需要打包这个应用,便于其他人安装它。

安装必须环境Link to this heading

目前,打包 Python 程序需要工具,有许多工具可以完成此项工作。在此教程中,我们将使用 setuptools 来打包我们的程序。这是推荐的打包工具(与 发布 分支合并)。我们仍旧使用 pip 来安装和卸载这个工具。现在,你需要安装这两个包。如果你需要帮助,你可以参考 如何通过 pip 安装 Django,你可以通过相同的方式安装 setuptools

打包你的应用Link to this heading

Python 的 打包 将以一种特殊的格式组织你的应用,意在方便安装和使用这个应用。Django 本身就被打包成类似的形式。对于一个小应用,例如 polls,这不会太难。

  1. 首先,在你的 Django 项目目录外创建一个名为 django-polls 的文件夹,用于盛放 polls

  2. polls 目录移入 django-polls 目录。

  3. 创建一个名为 django-polls/README.rst 的文件,包含以下内容:

    django-polls/README.rst
    Rst
    =====
    Polls
    =====
    
    Polls is a 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.
    
  4. 创建一个 django-polls/LICENSE 文件。选择一个非本教程使用的授权协议,但是要足以说明发布代码没有授权证书是 不可能的 。Django 和很多兼容 Django 的应用是以 BSD 授权协议发布的;不过,你可以自己选择一个授权协议。只要确定你选择的协议能够限制未来会使用你的代码的人。

  5. 接下来我们将创建 pyproject.tomlsetup.cfgsetup.py 文件,详细说明如何构建和安装该应用程序。对这些文件的全面解释超出了本教程的范围,但 setuptools 文档 有很好的解释。创建 django-polls/pyproject.tomldjango-polls/setup.cfgdjango-polls/setup.py 文件,内容如下:

    django-polls/pyproject.toml
    Toml
    [build-system]
    requires = ['setuptools>=40.8.0', 'wheel']
    build-backend = 'setuptools.build_meta:__legacy__'
    
    django-polls/setup.cfg
    Ini
    [metadata]
    name = django-polls
    version = 0.1
    description = A Django app to conduct web-based polls.
    long_description = file: README.rst
    url = https://www.example.com/
    author = Your Name
    author_email = yourname@example.com
    license = BSD-3-Clause  # Example license
    classifiers =
        Environment :: Web Environment
        Framework :: Django
        Framework :: Django :: X.Y  # Replace "X.Y" as appropriate
        Intended Audience :: Developers
        License :: OSI Approved :: BSD License
        Operating System :: OS Independent
        Programming Language :: Python
        Programming Language :: Python :: 3
        Programming Language :: Python :: 3 :: Only
        Programming Language :: Python :: 3.8
        Programming Language :: Python :: 3.9
        Topic :: Internet :: WWW/HTTP
        Topic :: Internet :: WWW/HTTP :: Dynamic Content
    
    [options]
    include_package_data = true
    packages = find:
    python_requires = >=3.8
    install_requires =
        Django >= X.Y  # Replace "X.Y" as appropriate
    
    django-polls/setup.py
    Python
    from setuptools import setup
    
    setup()
    
  6. 默认情况下,包中仅包含 Python 模块和包。 要包含其他文件,我们需要创建一个 MANIFEST.in 文件。 上一步中提到的 setuptools 文档更详细地讨论了这个文件。 要包含模板、README.rst 和我们的 LICENSE 文件,创建一个文件 django-polls/MANIFEST.in ,其内容如下:

    django-polls/MANIFEST.in
    Text
    include LICENSE
    include README.rst
    recursive-include polls/static *
    recursive-include polls/templates *
    
  7. 在应用中包含详细文档是可选的,但我们推荐你这样做。创建一个空目录 django-polls/docs 用于未来编写文档。额外添加一行至 django-polls/MANIFEST.in

    Code
    recursive-include docs *
    

    注意,现在 docs 目录不会被加入你的应用包,除非你往这个目录加几个文件。许多 Django 应用也提供他们的在线文档通过类似 readthedocs.org 这样的网站。

  8. 试着用 python setup.py sdist 构建你的应用包(在 django-polls 目录运行)。这将创建一个名为 dist 的目录,并构建你的新应用包,django-polls-0.1.tar.gz

更多关于打包的信息,见 Python 的 关于打包和发布项目的教程

使用你自己的包名Link to this heading

由于我们把 polls 目录移出了项目,所以它无法工作了。我们现在要通过安装我们的新 django-polls 应用来修复这个问题。

  1. 为了安装这个包,使用 pip (你早已 安装 pip, 对吗?):

    Code
    python -m pip install --user django-polls/dist/django-polls-0.1.tar.gz
    
  2. 幸运的话,你的 Django 项目应该再一次正确运行。启动服务器确认这一点。

  3. 通过 pip 卸载包:

    Code
    python -m pip uninstall django-polls
    

发布你的应用Link to this heading

现在,你已经对 django-polls 完成了打包和测试,准备好向世界分享它!如果这不是一个例子应用,你现在就可以这样做。

通过虚拟环境安装 Python 包Link to this heading

早些时候,我们以用户库的形式安装了投票应用。这样做有一些缺点。

  • 修改用户库会影响你系统上的其他 Python 软件。

  • 你将不能运行此包的多个版本(或者其它用有相同包名的包)。

通常,只有在维护多个 Django 项目时才会出现这些情况。当这样做时,最好的解决方法是使用 venv。使用此工具,你可以维护多个隔离的 Python 环境,每个环境都有其自己的库和包命名空间的副本。