高级教程:如何编写可复用的应用¶
本高级教程承接教程 8的内容。我们将把我们的网络投票应用转换成一个独立的 Python 包,以便在新的项目中重复使用并与他人分享。
如果您最近没有完成教程 1-8,我们建议您回顾一下,以便您的示例项目与下面描述的项目匹配。
可复用性很重要¶
设计、构建、测试和维护一个 Web 应用需要大量工作。许多 Python 和 Django 项目都面临着共同的问题。如果我们可以节省一些重复的工作,岂不是很好?
可复用性是 Python 的生存之道。Python 包索引 (PyPI) 提供了大量可用于您自己的 Python 程序的包。查看Django Packages,了解您可以添加到项目中的现有可复用应用。Django 本身也是一个普通的 Python 包。这意味着您可以将现有的 Python 包或 Django 应用组合到您自己的 Web 项目中。您只需要编写使您的项目独一无二的部分。
假设您正在启动一个新的项目,需要一个像我们一直在使用的投票应用一样的应用。如何使这个应用可复用?幸运的是,您已经走在了正确的道路上。在教程 1中,我们看到了如何使用include
将投票应用从项目级别的 URLconf 中解耦。在本教程中,我们将采取进一步的步骤,使该应用易于在新的项目中使用,并准备好发布供其他人安装和使用。
包?应用?
Python 包提供了一种将相关的 Python 代码分组以便于重复使用的方法。一个包包含一个或多个 Python 代码文件(也称为“模块”)。
可以使用import foo.bar
或from foo import bar
导入包。对于一个目录(例如polls
)要构成一个包,它必须包含一个特殊的__init__.py
文件,即使此文件为空。
Django *应用*是一个专门用于 Django 项目的 Python 包。一个应用可以使用常见的 Django 约定,例如具有models
、tests
、urls
和views
子模块。
稍后我们将使用术语*打包*来描述使 Python 包易于他人安装的过程。我们知道,这可能会有点令人困惑。
您的项目和您的可复用应用¶
完成前面的教程后,我们的项目应该如下所示
djangotutorial/
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.png
style.css
templates/
polls/
detail.html
index.html
results.html
tests.py
urls.py
views.py
templates/
admin/
base_site.html
您在教程 7中创建了djangotutorial/templates
,在教程 3中创建了polls/templates
。现在或许更清楚为什么我们选择为项目和应用程序分别使用模板目录:polls 应用的所有内容都在polls
中。它使应用程序自包含,更容易添加到新项目中。
polls
目录现在可以复制到新的 Django 项目中并立即重复使用。但是,它还没有准备好发布。为此,我们需要打包该应用,以便其他人更容易安装。
安装一些先决条件¶
当前 Python 打包的状态有点混乱,使用了各种工具。在本教程中,我们将使用setuptools来构建我们的包。这是推荐的打包工具(与distribute
分支合并)。我们还将使用pip来安装和卸载它。您现在应该安装这两个包。如果您需要帮助,可以参考如何使用 pip 安装 Django。您可以以同样的方式安装setuptools
。
打包您的应用¶
Python *打包*是指以特定格式准备您的应用,以便于安装和使用。Django 本身就是以这种方式打包的。对于像 polls 这样的小型应用,这个过程并不太难。
首先,为包创建一个父目录,该目录位于您的 Django 项目之外。将此目录命名为
django-polls
。为您的应用选择名称
为您的包选择名称时,请检查 PyPI 以避免与现有包发生命名冲突。我们建议使用
django-
前缀作为包名称,以标识您的包特定于 Django,并为您的模块名称使用相应的django_
前缀。例如,django-ratelimit
包包含django_ratelimit
模块。应用标签(即指向应用包的点路径的最后一部分)*必须*在
INSTALLED_APPS
中唯一。避免使用与任何 Django contrib 包相同的标签,例如auth
、admin
或messages
。将
polls
目录移动到django-polls
目录中,并将其重命名为django_polls
。编辑
django_polls/apps.py
,使name
引用新的模块名称,并添加label
以提供应用的简短名称django-polls/django_polls/apps.py
¶from django.apps import AppConfig class PollsConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "django_polls" label = "polls"
创建一个包含以下内容的文件
django-polls/README.rst
django-polls/README.rst
¶============ django-polls ============ django-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 = [ ..., "django_polls", ] 2. Include the polls URLconf in your project urls.py like this:: path("polls/", include("django_polls.urls")), 3. Run ``python manage.py migrate`` to create the models. 4. Start the development server and visit the admin to create a poll. 5. Visit the ``/polls/`` URL to participate in the poll.
创建一个
django-polls/LICENSE
文件。选择许可证不在本教程的范围内,但足以说明的是,公开发布的代码如果没有许可证,就*毫无用处*。Django 和许多与 Django 兼容的应用都在 BSD 许可证下分发;但是,您可以自由选择您自己的许可证。只需注意,您的许可证选择将影响谁能够使用您的代码。接下来,我们将创建
pyproject.toml
文件,该文件详细说明了如何构建和安装该应用。本教程不提供对该文件的完整解释,但Python 打包用户指南对此进行了很好的解释。使用以下内容创建django-polls/pyproject.toml
文件django-polls/pyproject.toml
¶[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "django-polls" version = "0.1" dependencies = [ "django>=X.Y", # Replace "X.Y" as appropriate ] description = "A Django app to conduct web-based polls." readme = "README.rst" requires-python = ">= 3.10" authors = [ {name = "Your Name", 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", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", ] [project.urls] Homepage = "https://www.example.com/"
许多常见的代码文件、Python 模块和包默认情况下都包含在包中。要包含其他文件,我们需要创建一个
MANIFEST.in
文件。要包含模板和静态文件,请使用以下内容创建一个django-polls/MANIFEST.in
文件django-polls/MANIFEST.in
¶recursive-include django_polls/static * recursive-include django_polls/templates *
包含详细的文档是可选的,但建议这样做。为将来的文档创建一个空目录
django-polls/docs
。请注意,除非您向其中添加一些文件,否则
docs
目录将不会包含在您的包中。许多 Django 应用还通过readthedocs.org等网站在线提供其文档。检查是否已安装 build 包(使用命令
python -m pip install build
),然后在django-polls
目录下运行python -m build
来构建你的包。这将创建一个名为dist
的目录,并将你的新包构建成源代码和二进制格式,分别为django-polls-0.1.tar.gz
和django_polls-0.1-py3-none-any.whl
。
有关打包的更多信息,请参阅 Python 的 打包和分发项目教程。
使用你自己的包¶
由于我们将 polls
目录移出了项目,它不再工作了。我们现在将通过安装新的 django-polls
包来解决这个问题。
作为用户库安装
以下步骤将 django-polls
安装为用户库。与系统范围安装相比,每个用户的安装有很多优点,例如可以在你没有管理员访问权限的系统上使用,以及防止包影响系统服务和其他用户。
请注意,每个用户的安装仍然会影响以该用户身份运行的系统工具的行为,因此使用虚拟环境是一个更稳健的解决方案(见下文)。
要安装该包,请使用 pip(你已经 安装了它,对吧?)
python -m pip install --user django-polls/dist/django-polls-0.1.tar.gz
更新
mysite/settings.py
以指向新的模块名称。INSTALLED_APPS = [ "django_polls.apps.PollsConfig", ..., ]
更新
mysite/urls.py
以指向新的模块名称。urlpatterns = [ path("polls/", include("django_polls.urls")), ..., ]
运行开发服务器以确认项目继续工作。
发布你的应用¶
现在我们已经打包并测试了 django-polls
,它已经准备好与世界分享了!如果这不仅仅是一个例子,你现在可以:
通过邮件将包发送给朋友。
将包上传到你的网站。
将包发布到公共存储库,例如 Python 包索引 (PyPI)。packaging.python.org 提供了 一个很好的教程 来完成此操作。
使用虚拟环境安装 Python 包¶
前面,我们将 django-polls
安装为用户库。这有一些缺点:
修改用户库可能会影响系统上的其他 Python 软件。
你将无法运行此包(或名称相同的其他包)的多个版本。
通常,只有在你维护多个 Django 项目时才会出现这种情况。当出现这种情况时,最好的解决方案是使用 venv。此工具允许你维护多个隔离的 Python 环境,每个环境都有自己的一份库和包命名空间副本。