Углублённый материал: Как создать повторно применяемое приложение

В продолжение Части 7 мы будем совершенствовать наше приложение Web-poll. Нам предстоит сделать настоящий пакет Python, который можно будет повторно использовать в новых проектах, а главное делиться им с другими разработчиками.

Если вы новичок и все ещё не выполняли занятия с 1 по 7 часть, мы настоятельно рекомендуем сделать это. Весь дальнейший материал опирается на предыдущие главы.

Смысл многократного использования

Большая часть работы уходит на проектирование, сборку, тестирование и конечно же поддержку веб приложения/компонента. У многих Python и Django проектов существуют схожие задачи и проблемы. Вот было бы здорово не повторять однажды проделанную работу, а сохранить её и использовать в будущем. Не правда ли?

Reusability is the way of life in Python. The Python Package Index (PyPI) has a vast range of packages you can use in your own Python programs. Check out Django Packages for existing reusable apps you could incorporate in your project. Django itself is also a normal Python package. This means that you can take existing Python packages or Django apps and compose them into your own web project. You only need to write the parts that make your project unique.

Let’s say you were starting a new project that needed a polls app like the one we’ve been working on. How do you make this app reusable? Luckily, you’re well on the way already. In Tutorial 1, we saw how we could 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 new projects and ready to publish for others to install and use.

Пакет? Приложение?

package в Python предоставляет способ группировать код Python для последующего повторного использования. Пакет содержит один или несколько файлов с кодом(также известны как «модули»).

Пакет может быть импортирован в ваш код так import foo.bar или так from foo import bar. Для того, чтобы обычная директория (к примеру polls) превратилась в пакет, обязательно создайте в этой директории файл __init__.py. Этот файл может быть пустым.

A Django application is a Python package that is specifically intended for use in a Django project. An application may use common Django conventions, such as having models, tests, urls, and views submodules.

Позднее мы будем использовать термин packaging для описания процесса создания пакетов для Python.

Ваш проект и ваши приложения

Если вы следовали нашим инструкциям из предыдущих частей урока, ваш каталог проекта должен иметь следующий вид:

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 таким образом, чтобы он был автономным. Вот теперь, при желании, этот каталог можно скопировать в наш новый проект.

И хоть приложение сейчас можно переносить из проекта в проект, этого не хватает для того, чтобы делиться с другими. Требуется оформить наше приложение особым образом и запаковать его.

Необходимые условия

Текущее состояние пакетов в Python немного запутано, содержит различные инструменты. В этом учебнике мы будем использовать setuptools для создания пакета. Это рекомендуемый инструмент для работы с пакетами (смерженый с форком distribute). Для его установки необходим pip. Установите эти два пакета. Доп. информацию можно получить по как установить Django используя pip. Вы можете установить setuptools аналогичным способом.

Создание пакета с вашим приложением

Пакеты Python созданы для удобного распространения и установки ваших приложений. Django использует аналогичную систему. Для простых приложений, как голосование, это не сложно.

  1. Первым делом создайте родительский каталог для polls вне вашего Django проекта. Назовите его django-polls.

    Выбор название для вашего приложения

    Выбирая название для вашего пакета, проверьте на PyPI нет ли уже пакета с таким названием. Рекомендуем добавлять префикс django- к названию пакета. Это поможет людям при поиске приложений для Django.

    Метка приложения (последняя часть пути к пакету приложения) должна быть уникальной в INSTALLED_APPS. Не используйте метки приложений Django из contrib packages, например, auth, admin или messages.

  2. Перенесите каталог polls в django-polls.

  3. Создайте файл django-polls/README.rst со следующим содержимым:

    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. Next we’ll create setup.cfg and setup.py files which detail how to build and install the app. A full explanation of these files is beyond the scope of this tutorial, but the setuptools documentation has a good explanation. Create the files django-polls/setup.cfg and django-polls/setup.py with the following contents:

    django-polls/setup.cfg
    [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.6
        Programming Language :: Python :: 3.7
        Programming Language :: Python :: 3.8
        Topic :: Internet :: WWW/HTTP
        Topic :: Internet :: WWW/HTTP :: Dynamic Content
    
    [options]
    include_package_data = true
    packages = find:
    
    django-polls/setup.py
    from setuptools import setup
    
    setup()
    
  6. Только модули и пакеты Python добавляются в пакет по умолчанию. Чтобы добавить другие файлы, необходимо создать файл MANIFEST.in. Документация setuptools содержит подробное описание этого файла. Чтобы указать добавление README.rst и LICENSE файлов, создайте django-polls/MANIFEST.in со следующим содержимым:

    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. Теперь попробуйте собрать ваш пакет выполнив python setup.py sdist (запустите в каталоге django-polls). Эта команда создаст каталог dist и соберет ваш новый пакет, django-polls-0.1.tar.gz.

For more information on packaging, see Python’s Tutorial on Packaging and Distributing Projects.

Использование ваших пакетов

Т.к. каталог polls был перенесен с каталога проекта, он перестал работать. Исправим это установив пакет django-polls.

Устанавливаем как библиотеку пользователя

Инструкция описывает как установить django-polls как библиотеку пользователя. Это лучше, чем устанавливать как системный пакет, таким образом он не влияет на системные сервисы и других пользователей, и позволяет установить пакеты без прав администратора.

Но такая установка влияет на системные приложения запущенные этим пользователем, virtualenv более надежный инструмент (смотрите ниже).

  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! Если бы это был не просто пример, вы бы могли:

Установка пакетов Python с использованием virtualenv

Раньше мы устанавливали пакет как библиотеку пользователя. В этом есть некоторые недостатки:

  • Изменение таких библиотек влияет на другие программы написанные на Python.
  • Вы не сможете использовать разные версии пакета (или пакеты с одинаковым названием).

Обычно такое происходит при работе над несколькими Django проектами. В таком случае лучше всего использовать virtualenv. Этот инструмент позволяет использовать независимые Python окружения, каждое со своими пакетами.