codecamp

Django4.0 开始-编写可重用程序

可重用性很重要

设计,构建,测试以及维护一个 web 应用要做很多的工作。很多 Python 以及 Django 项目都有一些常见问题。如果我们能保存并利用这些重复的工作岂不是更好?
可重用性是 Python 的根本。The Python Package Index (PyPI) 有许多大量的包,都可被用在你自己的 Python 项目中。同样可以在 Django Packages 中查找已发布的可重用应用,也可将其引入到你的项目中。Django 本身也是一个 Python 包,也就是说你可以将已有的 Python 包或 Django 应用并入你的项目。你只需要编写属于你的那部分即可。
假设你现在创建了一个新的项目,并且需要一个类似我们之前做的投票应用。你该如何复用这个应用呢?庆幸的是,其实你已经知道了一些。在 教程 1,我们使用过 ​include ​从项目级别的 URLconf 分割出 polls。在本教程中,我们将进一步使这个应用易用于新的项目中,并发布给其他人安装使用。

你的项目和可复用应用

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

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 工程,且立刻被复用。不过现在还不是发布它的时候。为了这样做,我们需要打包这个应用,便于其他人安装它。

安装必须环境

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

打包你的应用

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

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

当为你的包选一个名字时,避免使用像 ​PyPI ​这样已存在的包名,否则会导致冲突。当你创建你的发布包时,可以在模块名前增加 ​django-​ 前缀,这是一个很常用也很有用的避免包名冲突的方法。同时也有助于他人在寻找 Django 应用时确认你的 app 是 Django 独有的。
应用标签(指用点分隔的包名的最后一部分)在 ​INSTALLED_APPS ​中 必须 是独一无二的。避免使用任何与 ​Django contrib packages​ 文档中相同的标签名,比如 ​auth​,​admin​,​messages​。

2、将 ​polls目录移入 ​django-polls​ 目录。

3、创建一个名为 ​django-polls/README.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.toml​、​setup.cfg​ 和 ​setup.py​ 文件,详细说明如何构建和安装该应用程序。对这些文件的全面解释超出了本教程的范围,但 setuptools 文档 有很好的解释。创建 ​django-polls/pyproject.toml​、​django-polls/setup.cfg​ 和 ​django-polls/setup.py​ 文件,内容如下:

[build-system]
requires = ['setuptools>=40.8.0', 'wheel']
build-backend = 'setuptools.build_meta:__legacy__'
[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
from setuptools import setup

setup()

6、默认情况下,包中仅包含 Python 模块和包。 要包含其他文件,我们需要创建一个 ​MANIFEST.in​ 文件。 上一步中提到的 ​setuptools ​文档更详细地讨论了这个文件。 要包含模板、​README.rst​ 和我们的 ​LICENSE ​文件,创建一个文件 ​django-polls/MANIFEST.in​ ,其内容如下:

include LICENSE
include README.rst
recursive-include polls/static *
recursive-include polls/templates *

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

recursive-include docs *

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

8、试着构建你自己的应用包通过 ​ptyhon setup.py sdist​ (在 ​django-polls``​目录内)。这将创建一个名为 ​``dist​ 的目录并构建你自己的应用包, ​django-polls-0.1.tar.gz​。

使用你自己的包名

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

以下步骤将 ​django-polls​ 以用户库的形式安装。与安装整个系统的软件包相比,用户安装具有许多优点,例如可在没有管理员访问权的系统上使用,以及防止应用包影响系统服务和其他用户。
请注意,按用户安装仍然会影响以该用户身份运行的系统工具的行为,因此使用虚拟环境是更可靠的解决方案(请参见下文)。

1、为了安装这个包,使用 pip:

python -m pip install --user django-polls/dist/django-polls-0.1.tar.gz

2、幸运的话,你的 Django 项目应该再一次正确运行。启动服务器确认这一点。

3、通过 pip 卸载包:

python -m pip uninstall django-polls

发布你的应用

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

  • 通过邮件将你的包发送给朋友。
  • 将这个包上传至你的网站。
  • 将你的包发布至公共仓库,比如 ​the Python Package Index​ (​PyPI​)。 packaging.python.org 有一个不错的 教程 说明如何发布至公共仓库。

通过虚拟环境安装Python包

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

  • 修改用户库会影响你系统上的其他 Python 软件。
  • 你将不能运行此包的多个版本(或者其它用有相同包名的包)。

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


Django4.0 开始-编写你的第一个Django应用,第7部分
模型
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

Django4.0 模型和数据库

Django4.0 处理HTTP请求

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }