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

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

直近のチュートリアル 1 - 7 が終わっていないなら、一目通すことをおすすめします。例で作ったプロジェクトが以下の説明でも使われるからです。

再利用性の問題

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

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

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

パッケージ?アプリ?

Python の package を使うと、関連する Python コードをまとめて再利用しやすいようにできます。パッケージは、 Python コードのファイル ( 通称 "モジュール" ) を1つ以上含みます。

パッケージは import foo.bar または from foo import bar でインポートできます。パッケージ内のディレクトリ (例えば polls) は __init__.py という特殊なファイルを、空のファイルでもいいので含む必要があります。

Django アプリケーション は単なる Python パッケージで、 Django プロジェクトで使うことのみを意図したものです。アプリは一般的な Django の慣例に則っているでしょう。例えば modelstestsurlsviews のサブモジュールがあること、などです。

後に パッケージング という言葉を、他の人がインストールしやすいように 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.png
                style.css
        templates/
            polls/
                detail.html
                index.html
                results.html
        tests.py
        urls.py
        views.py
    templates/
        admin/
            base_site.html

すでに mysite/templatesチュートリアル 7 で、 polls/templatesチュートリアル 3 で作成しました。今となっては、なぜテンプレートディレクトリをプロジェクトとアプリケーションに分けたかが明確にわかるかもしれませんね。投票アプリケーションに関する全ては 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 の中で 必ず ユニークでなければなりません。 authadminmessages のような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):
        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.tomlsetup.cfgsetup.py ファイルを作りましょう。これはアプリケーションをどのようにビルドしインストールするかを記述するものです。これらのファイルのすべてを説明するのはこのチュートリアルの範疇を超えていますが、 setuptools docs の説明は役に立ちます。以下のように django-polls/pyproject.tomldjango-polls/setup.cfgdjango-polls/setup.py を作ってみましょう:

    django-polls/pyproject.toml
    [build-system]
    requires = ['setuptools>=40.8.0']
    build-backend = 'setuptools.build_meta'
    
    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.10
        Programming Language :: Python :: 3.11
        Programming Language :: Python :: 3.12
        Topic :: Internet :: WWW/HTTP
        Topic :: Internet :: WWW/HTTP :: Dynamic Content
    
    [options]
    include_package_data = true
    packages = find:
    python_requires = >=3.10
    install_requires =
        Django >= X.Y  # Replace "X.Y" as appropriate
    
    django-polls/setup.py
    from setuptools import setup
    
    setup()
    
  7. デフォルトでは、パッケージには Python のモジュールとパッケージだけがまとめられます。追加のファイルを含めるには、MANIFEST.in というファイルを作成する必要があります。前のステップで挙げた setuptools のドキュメントには、このファイルについて詳しい説明があります。テンプレート、README.rst、および LICENSE をパッケージに含めるには、django-polls/MANIFEST.in というファイルを作成し、その中に次のように書きます。

    django-polls/MANIFEST.in
    include LICENSE
    include README.rst
    recursive-include django_polls/static *
    recursive-include django_polls/templates *
    
  8. アプリケーションの詳細なドキュメントを含めるのは、任意ですが推奨されます。空のディレクトリ django-polls/docs を将来のドキュメンテーションのために作っておきましょう。 django-polls/MANAFEST.in に行を追加しておいてください:

    recursive-include docs *
    

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

  9. django-polls の中で python setup.py sdist を実行してパッケージをビルドしてみてください。これで 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. 新しいモジュール名を指すように 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環境を管理することができ、それぞれが独自のライブラリとパッケージの名前空間のコピーを持っています。

Back to Top