# Django 5.2.8 ドキュメント

# 高度なチュートリアル: 再利用可能アプリの書き方

この高度なチュートリアルは、チュートリアル その8 が終わったところから始まります。Web投票アプリケーションを、新しいプロジェクトで再利用でき、他の人に共有できる独立した Python のパッケージへと変えていきましょう。

最近、チュートリアル 1〜8 を完了したのではない場合は、以下に記載されている内容と一致するように、例題プロジェクトを見直すことをお勧めします。

## 再利用性の問題

Web アプリケーションの設計、開発、テスト、そしてメンテナンスには多大な労力が必要です。そして多くの Python プロジェクト、 Django プロジェクトは共通の問題を抱えています。この繰り返し作業を減らせたら良いと思いませんか？

再利用可能性はPythonの生き様とも言えるものです。Python Package Index (PyPI) にはあなたの Pythonプログラムに使用できる非常に幅広いパッケージが揃っています。あなたのプロジェクトに組み込むことのできる再利用可能なアプリについては、Django Packages を見てみてください。Django そのものも、普通のPython パッケージのひとつです。あなたは既存のPythonパッケージや Django アプリを選んで、自分の Web プロジェクトに組み込むことができます。つまり、あなたは自分のプロジェクトに特有の部分にだけ取り組めば良いのです。

例えば、投票アプリケーション（ちょうど今まで作ってきたものと似たようなもの）を必要とするプロジェクトを新しく開始したとしましょう。どうやって投票アプリケーションを再利用可能にしますか？運のいいことに、その方法はすでに会得済みです。 チュートリアル1 では、 `include` を使ってプロジェクトレベルの URLconf から投票アプリを分離する方法を学びました。このチュートリアルでは、アプリケーションを新規のプロジェクトで使いやすいようにし、いつでも別の場所でインストール/利用できるようにします。

パッケージ？アプリ？

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` は チュートリアル7 で作成し、`polls/templates` は チュートリアル3 で作成しました。今は、なぜプロジェクトとアプリケーションに別々のテンプレートディレクトリを設けることにしたのかが、より明確になったかもしれません。pollsアプリケーションに関連するすべてのものは `polls` フォルダ内にあります。これにより、アプリケーションは自己完結型となり、新しいプロジェクトに簡単に組み込むことができます。

今、 `polls` ディレクトリは新規の Django プロジェクトにコピーでき、すぐに再利用できる状態です。しかし公開するための準備が完璧というわけではありません。そのために、アプリをパッケージにして別の場所でインストールしやすいようにする必要があります。

## 事前に必要な物をインストールする

Python のパッケージングの現状は、複数のツールがあることで少しややこしいです。このチュートリアルでは setuptools をパッケージに使用します。これはおすすめのパッケージングツールです( forkされていた `distribute` はマージされました)。終わった後にアンインストールするために pip も使います。今はこの 2 つのパッケージをインストールしておいてください。分からなければ Django をpip でインストールする. を参照してください。 `setuptools` も同じ方法でインストールできます。

## アプリケーションをパッケージングする

Python において パッケージング とは、特定のフォーマットでアプリを作っておくことです。このフォーマットは簡単にインストールして使えます。 Django 自体もこのようにパッケージ化されています。投票アプリのような小さなものでは、このプロセスはそれほど難しいものではありません。

1. まず、Django プロジェクトの外に、パッケージのための親ディレクトリを作成します。以降、このディレクトリを `django-polls` と呼びます。

   アプリケーションの名前を決める

   パッケージ名を決める際には、既存のパッケージとの名前の衝突を避けるために PyPI をチェックしてください。パッケージ名には Django 固有のパッケージであることを示すために `django-` という接頭辞をつけ、モジュール名にはそれに対応する `django_` という接頭辞を付けることを推奨します。例えば、 `django-ratelimit` パッケージは `django_ratelimit` モジュールを含んでいます。

   アプリケーションラベル (すなわち、アプリケーションパッケージへのパス（ドット区切り）の最後の部分) は `INSTALLED_APPS` の中で 必ず ユニークでなければなりません。 `auth` 、 `admin` 、 `messages` のようなDjango contrib packages と同じラベルを使うことは避けてください。

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):
           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パッケージユーザーガイド に良い説明があります。以下の内容で `django-polls/pyproject.toml` ファイルを作成してください。

   `django-polls/pyproject.toml`

       [build-system]
       requires = ["setuptools>=77.0.3"]
       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"
       license = "BSD-3-Clause"
       requires-python = ">= 3.12"
       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",
           "Operating System :: OS Independent",
           "Programming Language :: Python",
           "Programming Language :: Python :: 3",
           "Programming Language :: Python :: 3 :: Only",
           "Programming Language :: Python :: 3.12",
           "Programming Language :: Python :: 3.13",
           "Programming Language :: Python :: 3.14",
           "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` を作成してください。

   `MANIFEST.in` に対象のファイルを追加しないと `docs` ディレクトリがパッケージに含まれないことに注意してください。多くの Django アプリではドキュメントを readthedocs.org のようなサイトを通して提供しています。

   Django や Python 本体を含む多くの Pythonプロジェクトでは、 Sphinx を利用してドキュメントを構築しています。 Sphinx を使用する際は、 Intersphinx を設定し、プロジェクトの `intersphinx_mapping` 値に Django の値を含めることで、 Django ドキュメントにリンクすることができます。

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

   これを設定すると、 Django ドキュメントと同様に、 "`:attr:`django.test.TransactionTestCase.databases``" などの特定のエントリに相互リンクできるようになります。

9. 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` が作成されます。

パッケージングに関するより豊富な情報は プロジェクトのパッケージ化と配布に関するチュートリアル にあります。

## 自分のパッケージを使ってみる

`polls` ディレクトリはプロジェクト外に移動したので、これはもう動きません。代わりにできたての `django-polls` パッケージを使ってみましょう。

ユーザーライブラリとしてインストールする

以下のステップは `django-polls` をユーザーライブラリとしてインストールするものです。ユーザー単位でのインストールはシステム全体でのインストールよりも多くの利点があります。管理者アクセス権を持っていないシステム上で使用可能というだけでなく、パッケージがシステムサービスやマシン上の他ユーザーに影響を与えるのを防げます。

ユーザーごとのインストールは、そのユーザーとして実行されるシステムツールの動作に影響を与える可能性があるため、仮想環境を使用する方がより堅牢なソリューションであることに注意してください（以下を参照）。

1. パッケージをインストールするためには、pip を利用してください (すでに インストール していますよね?):

       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` のパッケージを作り、テストしました。世界に共有するときです！これが単なる例でなければこうします:

- パッケージを友人にメールで送る

- 自身の Web サイトにアップロードする

- Post the package on a public repository, such as the Python Package Index (PyPI). There is a good tutorial for doing this.

## 仮想環境でのPythonパッケージのインストール

先ほど、 `django-polls` をユーザライブラリとしてインストールしました。これにはいくつかの欠点があります:

- ユーザーライブラリの変更はシステム上の他の Python ソフトウェアに影響を与えるおそれがあります

- このパッケージの複数バージョン (もしくは同じ名前の別のもの) を実行できません

通常、このような状況は複数の Django プロジェクトを管理している場合にのみ発生します。このような場合、最良の解決策は venv を使うことです。このツールを使うと、複数の分離されたPython環境を管理することができ、それぞれが独自のライブラリとパッケージの名前空間のコピーを持っています。