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

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

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

再利用性の問題

Web アプリケーションの設計、開発、テスト、そしてメンテナンスには多大な労力が必要です。そして多くの 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.

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

パッケージ?アプリ?

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

パッケージは 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.

後に パッケージング という言葉を、他の人がインストールしやすいように Python パッケージを作るプロセスを表すのに用います。少し混乱するかもしれませんね。

プロジェクトと再利用可能アプリ

前のチュートリアルを終えると、プロジェクトはこのようになっているはずです:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py
    polls/
        __init__.py
        admin.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

すでに mysite/templatesチュートリアル 7 で、 polls/templatesチュートリアル 3 で作成しました。今となっては、なぜテンプレートディレクトリをプロジェクトとアプリケーションに分けたかが明確にわかるかもしれませんね。投票アプリケーションに関する全ては polls にあります。アプリケーションが自己完結していて、新規のプロジェクトにも導入しやすくなっています。

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

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

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

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

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

  1. はじめに、 polls の親ディレクトリを、 Django プロジェクトの外に作りましょう。 django-polls というディレクトリにします。

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

    パッケージの名前を決めるときは、 PyPI のようなリソースをチェックして、すでにあるパッケージとの名前の衝突を避ける必要があります。 Django アプリケーションのパッケージを作って配布する際には、モジュール名の先頭に django- を付けるのがよいでしょう。こうすると、 Django アプリを探している人にとって、あなたのアプリが Django 特化のものであると判別しやすくなります。

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

  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/MANAFEST.in に行を追加しておいてください:

    recursive-include docs *
    

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

  8. python setup.py sdist でパッケージをビルドしてみましょう (django-polls 内で実行してください) 。これによって dist というディレクトリと、新しいパッケージである django-polls-0.1.tar.gz が作られます。

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

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

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

virtualenv に Python パッケージをインストールする

これまでは投票アプリをユーザーライブラリにインストールしてきました。これにはいくつか欠点があります:

  • ユーザーライブラリの変更はシステム上の他の Python ソフトウェアに影響を与えるおそれがあります
  • このパッケージの複数バージョン (もしくは同じ名前の別のもの) を実行できません

通常このような問題が起こるのは、複数の Django プロジェクトを管理している場合だけです。一番の解決方法は、 virtualenv を利用することです。このツールを使えば、複数の独立した Python 環境を持つことができます。各 Python 環境はそれぞれに、ライブラリのコピーやパッケージの名前空間を持ちます。

Back to Top