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

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

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

再利用性の問題

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

再利用は、 Python ではごく当たり前のことです。 Python Package Index (PyPI) には様々なパッケージが登録されており、それらはすべてあなたの Python プログラム上で使えます。 Django Packages にもプロジェクトに組み込める再利用可能なアプリケーションがあるので見てみてください。 Django 自体も単なる Python パッケージです。つまり既存の Python パッケージまたは Django アプリケーションを使って、自分の Web プロジェクトを構成できるということです。必要なのはそのプロジェクト独自の部品を書くことだけです。

例えば、投票アプリケーション(ちょうど今まで作ってきたものと似たようなもの)を必要とするプロジェクトを新しく開始したとしましょう。どうやって投票アプリケーションを再利用可能にしますか?運のいいことに、その方法はすでに会得済みです。 チュートリアル3 では、 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
        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 simple 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::
    
        url(r'^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. 次に setup.py ファイルを作りましょう。これはアプリケーションがどのようにビルド、インストールされるかを提供するものです。このファイルの網羅的な説明はこのチュートリアルの範疇を超えていますが、 setuptools docs には役立つ説明があります。以下のように django-polls/setup.py ファイルを作ってみましょう:

    django-polls/setup.py
    import os
    from setuptools import find_packages, setup
    
    with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
        README = readme.read()
    
    # allow setup.py to be run from any path
    os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
    
    setup(
        name='django-polls',
        version='0.1',
        packages=find_packages(),
        include_package_data=True,
        license='BSD License',  # example license
        description='A simple Django app to conduct Web-based polls.',
        long_description=README,
        url='https://www.example.com/',
        author='Your Name',
        author_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',  # example license
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            # Replace these appropriately if you are stuck on Python 2.
            'Programming Language :: Python :: 3',
            'Programming Language :: Python :: 3.4',
            'Programming Language :: Python :: 3.5',
            'Topic :: Internet :: WWW/HTTP',
            'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
        ],
    )
    
  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 が作られます。

パッケージングに関するより豊富な情報は Tutorial on Packaging and Distributing Projects にあります。

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

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

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

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

ユーザー単位でのインストールは依然、そのユーザーのシステムツールの振る舞いに影響をあたえます。なので virtualenv はより確実な解決になります (下記を参照してください) 。

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

    pip install --user django-polls/dist/django-polls-0.1.tar.gz
    
  2. 運が良ければ Django プロジェクトは再度、正常に動作します。確認するために再びサーバーを起動します。

  3. パッケージをアンインストールするには pip を使います:

    pip uninstall django-polls
    

アプリを公開する

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

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

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

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

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

Back to Top