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

Этот продвинутый учебник начинается с того места, на котором остановился Tutorial 8. Мы превратим наш web-poll в самостоятельный пакет Python, который можно использовать в новых проектах и передавать другим людям.

Если вы недавно не проходили уроки 1-8, мы рекомендуем вам ознакомиться с ними, чтобы убедиться, что ваш пример проекта соответствует описанному ниже.

Возможность повторного использования имеет значение

Это большая работа по проектированию, созданию, тестированию и поддержке веб-приложения. Многие проекты Python и Django имеют общие проблемы. Разве не было бы здорово, если бы мы могли спасти часть этой повторяющейся работы?

Повторное использование - это образ жизни в Python. Индекс пакетов Python (PyPI) содержит широкий спектр пакетов, которые вы можете использовать в своих собственных программах Python. Проверьте Django Packages для существующих приложений многократного использования, которые вы можете включить в свой проект. Сам Django также является обычным пакетом Python. Это означает, что вы можете взять существующие пакеты Python или приложения Django и объединить их в свой собственный веб-проект. Вам нужно только написать части, которые делают ваш проект уникальным.

Допустим, вы начинаете новый проект, для которого нужно приложение для опросов, такое как то, над которым мы работали. Как вы делаете это приложение многоразовым? К счастью, у вас уэн почти все готово. В Tutorial 1 мы увидели, как можно отделить опросы от URLconf уровня проекта, используя include. В этом руководстве мы предпримем дальнейшие шаги, чтобы сделать приложение простым в использовании в новых проектах и готовым к публикации для установки и использования другими пользователями.

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

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

Пакет может быть импортирован с помощью import foo.bar или from foo import bar. Чтобы каталог (например, polls) сформировал пакет, он должен содержать специальный файл __init__.py, даже если этот файл пуст.

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

Вы создали djangotutorial/templates в Tutorial 7 и polls/templates в Tutorial 3. Теперь, возможно, стало понятнее, почему мы решили использовать отдельные каталоги шаблонов для проекта и приложения: все, что является частью приложения polls, находится в polls. Это делает приложение автономным и упрощает его использование в новом проекте.

Каталог polls теперь может быть скопирован в новый проект Django и немедленно использован повторно. Но он еще не совсем готов к публикации. Для этого нам нужно упаковать приложение, чтобы другим было легко его установить.

Установка некоторых предварительных условий

Современное состояние упаковки Python представляет собой некоторую неразбериху с различными инструментами. В данном руководстве мы будем использовать setuptools для сборки нашего пакета. Это рекомендуемый инструмент упаковки (объединенный с форком distribute). Мы также будем использовать pip для его установки и удаления. Теперь вам следует установить эти два пакета. Если вам нужна помощь, вы можете обратиться к how to install Django with pip. Аналогичным образом можно установить setuptools.

Упаковка вашего приложения

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

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

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

    При выборе имени для вашего пакета проверьте PyPI, чтобы избежать конфликтов имен с существующими пакетами. Мы рекомендуем использовать префикс django- для имен пакетов, чтобы идентифицировать ваш пакет как специфичный для Django, и соответствующий префикс django_ для имени вашего модуля. Например, пакет django-ratelimit содержит модуль django_ratelimit.

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

  2. Переместите каталог polls в каталог django-polls и переименуйте его в django_polls.

  3. Отредактируйте 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"
    
  4. Создайте файл 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.
    
  5. Создайте файл django-polls/LICENSE. Выбор лицензии выходит за рамки данного руководства, но достаточно сказать, что код, выпущенный публично без лицензии, бесполезен. Django и многие Django-совместимые приложения распространяются по лицензии BSD; однако вы можете выбрать собственную лицензию. Просто знайте, что ваш выбор лицензии повлияет на то, кто может использовать ваш код.

  6. Далее мы создадим файл pyproject.toml, в котором подробно описано, как создать и установить приложение. Полное описание этого файла выходит за рамки данного руководства, но в Python Packaging User Guide есть хорошее объяснение. Создайте файл 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/"
    
  7. Многие распространенные файлы, а также модули и пакеты Python включены в пакет по умолчанию. Чтобы включить дополнительные файлы, нам нужно создать файл MANIFEST.in. Чтобы включить шаблоны и статические файлы, создайте файл django-polls/MANIFEST.in со следующим содержимым:

    django-polls/MANIFEST.in
    recursive-include django_polls/static *
    recursive-include django_polls/templates *
    
  8. Необязательно, но рекомендуется включать в приложение подробную документацию. Создайте пустой каталог django-polls/docs для будущей документации.

    Обратите внимание, что каталог docs не будет включен в ваш пакет, если вы не добавите в него некоторые файлы. Многие приложения Django также предоставляют свою документацию в Интернете через такие сайты, как readthedocs.org.

    Многие проекты на Python, включая Django и сам Python, используют Sphinx для создания своей документации. Если вы решите использовать Sphinx, вы можете перейти по ссылке на документацию Django, настроив Intersphinx и указав значение для Django в intersphinx_mapping вашего проекта.:

    intersphinx_mapping = {
        # ...
        "django": (
            "https://docs.djangoproject.com/en/stable/",
            None,
        ),
    }
    

    После этого вы можете создавать перекрестные ссылки на определенные записи таким же образом, как в документах Django, например «:attr:`django.test.TransactionTestCase.databases`».

  9. Убедитесь, что пакет build установлен (python -m pip install build) и попробуйте создать свой пакет, запустив python -m build внутри django-polls. При этом создается каталог с именем dist и создается ваш новый пакет в исходном и двоичном форматах django-polls-0.1.tar.gz и django_polls-0.1-py3-none-any.whl.

Для получения дополнительной информации о пакетировании см. Учебное пособие Python по упаковке и распространению проектов.

Используя свой собственный пакет

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

Установка в качестве пользовательской библиотеки

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

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

  1. Для установки пакета используйте pip (вы ведь уже installed it, верно?):

    python -m pip install --user django-polls/dist/django-polls-0.1.tar.gz
    
  2. Обновите mysite/settings.py, чтобы указать на новое название модуля:

    INSTALLED_APPS = [
        "django_polls.apps.PollsConfig",
        ...,
    ]
    
  3. Обновите mysite/urls.py, чтобы указать на новое название модуля:

    urlpatterns = [
        path("polls/", include("django_polls.urls")),
        ...,
    ]
    
  4. Запустите сервер разработки, чтобы убедиться, что проект продолжает работать.

Публикация вашего приложения

Теперь, когда мы упаковали и протестировали django-polls, он готов поделиться с миром! Если бы это был не просто пример, вы могли бы сейчас:

Установка пакетов Python в виртуальной среде

Ранее мы устанавливали django-polls как пользовательскую библиотеку. У этого есть некоторые недостатки:

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

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

Вернуться на верх