Python Web フレームワーク: 第 1 回 Django と Python を使って Web 開発

Python Django Webフレームワーク、そのインストールからWebサイトの完成まで

この記事は2回シリーズの第1回として、Djangoを紹介します。Djangoはオープンソースの、MVC(model-view-controller)スタイルのWebアプリケーション・フレームワークであり、Pythonプログラミング言語を活用しています。Djangoを使うと、高品質で維持管理の容易なデータベース・ドリブンのWebアプリケーションを、数分で作成することができます。

Ian Maurer (ian@itmaurer.com), Senior Consultant, Brulant, Inc.

Author photo: Ian MaurerIan MaurerはBrulant, Inc.のシニア・コンサルタントであり、コンシューマー商品や小売りなど様々な業界のために、オープンソース技術やIBM WebSphere技術を使った統合eコマース・ソリューションの開発を専門としています。彼はオハイオ州北東部に住み、クリーブランド地区のPython Interest Groupのメンバーでもあります。



2006年 6月 06日

Djangoプロジェクトは、オンライン新聞のWebサイトを元にカスタム構築されたフレームワークであり、2005年の7月にオープンソースとしてリリースされました。Djangoフレームワークのコア・コンポーネントには、次のようなものがあります。

  • モデル作成のための、オブジェクト・リレーショナルなマッピング
  • エンドユーザーのために作られた、洗練された管理者インターフェース
  • 優雅なURLデザイン
  • 設計者に使いやすいテンプレート言語
  • キャッシュ・システム

この記事は、Python Webフレームワークに関する2回シリーズの第1回です。第2回では、TurboGearsフレームワークについて紹介します。

この記事で使用するコードを使用し、理解するためには、Pythonをインストールし、初心者レベルで使いこなせる必要があります。まず自分がPythonを持っているかを調べ、また、python -Vとタイプして、どのバージョンを持っているかを調べてください。Djangoには、少なくともバージョン2.3.5が必要です。これはPythonのWebサイトから入手することができます(記事の最後の参考文献にリンクがあります)。また少なくとも、ある程度はMVCアーキテクチャーに慣れている必要があります。

Djangoをインストールする

この記事では、最近Djangoフレームワークに対して行われた改善を利用するために、開発バージョンのDjangoを使います。皆さんには、0.95リリースまで、このバージョンを使うようにお勧めします。最新リリースについては、DjangoのWebサイトを調べてください(これについても参考文献にリンクがあります)。

Djangoをダウンロードし、インストールするには、次のようにします。

リスト1. Djangoをダウンロードし、インストールする
~/downloads# svn co http://code.djangoproject.com/svn/django/trunk/ django_src
~/downloads# cd django_src
~/downloads# python setup.py install

Djangoのadminツール

Djangoをダウンロードすると、パス上にadminツール、django-admin.pyがあるはずです。リスト2は、このadminツールで利用できるコマンドの一部を示しています。

リスト2. Djangoの管理ツールを使う
~/dev$ django-admin.py
usage: django-admin.py action [options]
actions:
  adminindex [modelmodule ...]
    Prints the admin-index template snippet for the given model
    module name(s).

  ... snip ...

  startapp [appname]
    Creates a Django app directory structure for the given app name
    in the current directory.

  startproject [projectname]
    Creates a Django project directory structure for the given
    project name in the current directory.

  validate
    Validates all installed models.

options:
  -h, --help		show this help message and exit
  --settings=SETTINGS	Python path to settings module, e.g.
			"myproject.settings.main". If this isn't
			provided, the DJANGO_SETTINGS_MODULE
			environment variable will be used.
  --pythonpath=PYTHONPATH
			Lets you manually add a directory the Python
			path, e.g. "/home/djangoprojects/myproject".

Djangoのプロジェクトとアプリケーション

Djangoのプロジェクトを開始するには、django-adminのstartprojectコマンドを使います(下記)。

リスト3. プロジェクトを開始する
	~/dev$ django-admin.py startproject djproject

上記のコマンドによって、djprojectというディレクトリーが作成されます。このディレクトリーには、Djangoのプロジェクトを実行するために必要となる、基本的なコンフィギュレーション・ファイルが含まれています。

リスト4. djprojectディレクトリーの内容
__init__.py
manage.py
settings.py
urls.py

このプロジェクトでは、「jobs」という、求人掲示板アプリケーションを構築します。アプリケーションを作成するためには、manage.pyスクリプトを使います。これはプロジェクト固有のdjango-admin.pyスクリプトであり、このスクリプトにはsettings.pyファイルが自動的に与えられます。

リスト5. manage.py startappを使う
~/dev$ cd djproject
~/dev/djproject$ python manage.py startapp jobs

これによって、モデル用に1つのPythonモジュールを持ち、ビュー用にもう1つのPythonモジュールを持つ、骨組みだけのアプリケーションが作成されます。jobsディレクトリーには、次のようなファイルが含まれています。

リスト6. jobsアプリケーション・ディレクトリーの内容
__init__.py
models.py
views.py

プロジェクト内でのアプリケーションの位置は、新たにDjango開発を始める人のために作られた単なる習慣であり、そのように要求されているわけではありません。幾つかのプロジェクトの間で様々なアプリケーションをいじり始めたら、アプリケーションをそれぞれ独自のモジュール名前空間に置き、設定ファイルとマスターURLファイルを使ってそれらを結びつけることができます。とりあえずは、ここで示すステップに従います。

Djangoが新しいアプリケーションを理解するようにするには、settings.pyファイルのINSTALLED_APPSフィールドにエントリーを追加する必要があります。この求人掲示板アプリケーションでは、djproject.jobsというストリングを追加します。

リスト7. settings.pyにエントリーを追加する
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'djproject.jobs',
)

モデルを作成する

Djangoには、Pythonのオブジェクト・インターフェースを通して動的にデータベースにアクセスするための、独自のORM(object-relational mapper)ライブラリーが付いてきます。Pythonのインターフェースは非常に使いやすく強力ですが、もし必要な場合には、SQLを直接使うこともできます。

ORMは現在、PostgreSQLとMySQL、SQLite、そしてMicrosoft® SQLをサポートしています。

この例では、データベース・バックエンドとしてSQLiteを使います。SQLiteはコンフィギュレーションが不要な軽量のデータベースであり、単純なファイルとしてディスク上に置かれます。SQLiteを使うためには、setuptoolsを使って単純にpysqliteライブラリーをインストールします(setuptoolsと、特にeasy_installツール(別にインストールが必要です)に関して詳しくは、参考文献を見てください)。

easy_install pysqlite

モデルに対して作業を始める前に、設定ファイルの中でデータベースをコンフィギュレーションします。SQLiteで必要なのは、データベース・エンジンと名前を指定することだけです。

リスト8. settings.pyでデータベースをコンフィギュレーションする
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = '/path/to/dev/djproject/database.db'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

この求人掲示板アプリケーションには、LocationとJob という、2つのタイプのオブジェクトがあります。Locationには、city(市)、state(州・・オプション)、そしてcountry(国)のフィールドがあります。またJobには、location(場所)とtitle(肩書き)、description(仕事内容)、publish date(掲載日)のフィールドがあります。

リスト9. jobs/models.pyモジュール
from django.db import models

class Location(models.Model):
    city = models.CharField(maxlength=50)
    state = models.CharField(maxlength=50, null=True, blank=True)
    country = models.CharField(maxlength=50)

    def __str__(self):
        if self.state:
            return "%s, %s, %s" % (self.city, self.state, self.country)
        else:
            return "%s, %s" % (self.city, self.country)

class Job(models.Model):
    pub_date = models.DateField()
    job_title = models.CharField(maxlength=50)
    job_description = models.TextField()
    location = models.ForeignKey(Location)

    def __str__(self):
        return "%s (%s)" % (self.job_title, self.location)

__str__ メソッドはPythonの特別なクラス・メソッドであり、オブジェクトのストリング表現を返します。DjangoはAdminツールにオブジェクトを表示する際に、このメソッドを頻繁に使います。

モデルに対するデータベース・スキーマを見るには、manage.pyのsqlコマンドを実行します。まだ、このスキーマはアクティブにしません。

リスト10. manage.pyのsqlコマンドを使ってデータベース・スキーマを見る
~/dev/djproject$ python manage.py sql jobs

BEGIN;
CREATE TABLE "jobs_job" (
    "id" integer NOT NULL PRIMARY KEY,
    "pub_date" date NOT NULL,
    "job_title" varchar(50) NOT NULL,
    "job_description" text NOT NULL,
    "location_id" integer NOT NULL
);
CREATE TABLE "jobs_location" (
    "id" integer NOT NULL PRIMARY KEY,
    "city" varchar(50) NOT NULL,
    "state" varchar(50) NULL,
    "country" varchar(50) NOT NULL
);
COMMIT;

モデルを初期化し、インストールするには、データベース同期化コマンド、syncdbを実行します(下記)。

~/dev/djproject$ python manage.py syncdb

syncdbコマンドが、スーパーユーザー・アカウントを作成するように言ってくることに注意してください。これは、INSTALLED_APPS設定の中にデフォルトでdjango.contrib.authアプリケーション(基本的なユーザー認証機能を提供します)が用意されているためです。スーパーユーザーの名前とパスワードは、次のセクションで説明するadminツールにログインする際に使われます。これはDjangoのadminに対するスーパーユーザーであって、皆さんのシステムのスーパーユーザーではないことを忘れないでください。


クエリー・セット

Djangoのモデルは、objectsという、デフォルトのManagerクラスによってデータベースにアクセスします。例えば、すべてのJobのリストを出力するためには、objectsマネージャーのallメソッドを使います。

リスト11. すべてのjobを出力する
>>> from jobs.models import Job
>>> for job in Job.objects.all():
...     print job

このManagerクラスは、filterとexcludeという、フィルター・メソッドも持っています。Filterは、ある条件に合致するすべてのオブジェクトを取得し、excludeは逆に、ある条件に合致しない全オブジェクトを取得します。下記のクエリーでは、同じ結果が得られるはずです(「gteは「greater than or equal」を意味し、「lt」は「less than」を意味します)。

リスト12. Excludeとfilter
>>> from jobs.models import Job
>>> from datetime import datetime
>>> q1 = Job.objects.filter(pub_date__gte=datetime(2006, 1, 1))
>>> q2 = Job.objects.exclude(pub_date__lt=datetime(2006, 1, 1))

filterメソッドとexcludeメソッドはQuerySetオブジェクトを返します。QuerySetオブジェクトは、つなげてチェーンにすることができ、さらにはジョインを実行することもできます。下記のq4クエリーは、2006年の1月1日以降にオハイオ州クリーブランドで掲載されたjobを見つけます。

リスト13. さらにExcludeとfilterを行う
>>> from jobs.models import Job
>>> from datetime import datetime
>>> q3 = Job.objects.filter(pub_date__gte=datetime(2006, 1, 1))
>>> q4 = q3.filter(location__city__exact="Cleveland",
...                location__state__exact="Ohio")

QuerySetが怠け者であるのは結構なことです。これはつまり、QuerySetは評価されるまでデータベースに対して実行しない、ということであり、従って即座に行われるクエリーよりも、ずっと高速に実行します。

この怠け方をPythonの『スライス(slice)』機能と組み合わせると、便利なことができます。下記のコードでは、すべてのレコードをリクエストしてから必要なレコードをスライスするのではなく、実際のSQLクエリーでOFFSETを5、LIMITを10とすることによって、大幅にパフォーマンスを向上させています。

リスト14. Pythonのslice機能
>>> from jobs.models import Job
>>> for job in Job.objects.all()[5:15]
...     print job

注記: QuerySetの中のレコード数を数えるには、countメソッドを使います。Pythonのlenメソッドは、完全な評価を行ってから、レコードとして返された行を数えます。一方countメソッドは実際のSQL COUNTを行い、こちらの方がずっと速いのです。データベースの管理者は、きっとあなたに感謝することでしょう。

リスト15. レコードを数える
>>> from jobs.models import Job
>>> print "Count = ", Job.objects.count()       # GOOD!
>>> print "Count = ", len(Job.objects.all())    # BAD!

詳しくは、参考文献のセクションに挙げた、Djangoの「Database API reference」へのリンクを見てください。


管理者ツール

Djangoの最大の魅力は、その洗練されたadminインターフェースです。このツールは、エンドユーザーを念頭に作成されており、皆さんのプロジェクトにとって強力なデータ入力ツールになります。

このadminツールは、Djangoに付属しているアプリケーションです。このツールを使用するためには、(jobsアプリケーションの場合と同じように)まずインストールする必要があります。最初のステップは、このアプリケーションのモジュール(django.contrib.admin)を、INSTALLED_APPS設定に追加することです。

リスト16. settings.pyを変更する
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'djproject.jobs',
    'django.contrib.admin',
)

/admin URLからadminツールが使えるようにするには、プロジェクトのurls.pyファイルに用意されているコメント行のコメントを外すだけです。次のセクションでは、URLコンフィギュレーションについて詳しく説明します。

リスト17. urls.pyを変更してadminツールを使えるようにする
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^admin/', include('django.contrib.admin.urls.admin')),
)

adminアプリケーションには独自のデータベース・モデルがあり、これをインストールする必要があります。そのために、再度syncdbコマンドを使います。

python manage.py syncdb

adminツールを見るためには、Djangoに付属しているテスト・サーバーを使います。

リスト18. テスト・サーバーを使ってadminツールを見る
~/dev/djproject$ python manage.py runserver
Validating models...
0 errors found.

Django version 0.95 (post-magic-removal), using settings 'djproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).

これで、http://localhost:8000/adminにあるadminツールにまでナビゲートすることができ、先ほど作成したスーパーユーザー・アカウントを使ってログインすることができます。まだ、どのモジュールも利用できません。

adminツールからクラスを利用できるようにするためには、それに対するAdminサブクラスを作ります。次に、このサブクラスにクラス属性を追加することによって、それぞれのクラスの管理方法をカスタム化します。リスト19は、adminツールにLocationクラスを追加する方法を示しています。

リスト19. adminツールを使ってLocationクラスを追加する
class Location(meta.Model):
    ...
    class Admin:
        list_display = ("city", "state", "country")

こうすると、adminインターフェースからLocationレコードを作成し、更新し、削除することができるようになります。

図1. adminツールでlocationを編集する
Editing locations withthe Admin tool

これで、list_displayクラス属性のcity、state、countryで指定される通りにレコードをリストアップし、ソートすることができます。

図2. adminツールでlocationをリストアップする
Listing locations withthe Admin tool

adminツールには、各タイプのモデル・クラスを管理するための無数のオプションがあります。リスト20は、その幾つかの例をJobクラスに適用したものです。

リスト20. モデル・クラスを管理するためのオプション
class Job(meta.Model):
    ...
    class Admin:
	list_display = ("job_title", "location", "pub_date")
	ordering = ["-pub_date"]
	search_fields = ("job_title", "job_description")
	list_filter = ("location",)

上記の設定では、jobレコードをリストする際に、そのtitle(肩書き)、location(場所)、published date(掲載日)が使われます。jobは、一番最近のものを先頭として、掲載日の新しい順に並べられます(マイナス記号は降順を示します)。ユーザーはtitleとdescription(仕事内容)でjobを見つけることができ、一方管理者は、locationでレコードにフィルターをかけることができます。

図3. adminツールでjobをリストアップする
Listing jobs withthe admin tool

URLスキームを設計する

DjangoのURLディスパッチ・システムは、URLストリング・パターンを(『ビュー』と呼ばれる)Pythonモジュールにマップする、正規表現のコンフィギュレーション・モジュールを使います。このシステムでは、基礎となるコードからURLが完全に分離されるため、細かなコントロールが可能になり、また柔軟性も高めることができます。

URLコンフィギュレーションを開始するためのデフォルトとして、(settings.pyモジュールの、ROOT_URLCONFの値によって)urls.pyモジュールが作成され、定義されます。URLコンフィギュレーション・ファイルに対する唯一の要求事項は、urlpatternsというパターンを定義するオブジェクトを含まなければならない、ということのみです。

求人掲示板アプリケーションは、こうしたURLマッピングを介してアクセスされる、インデックス・ビューと詳細ビューから始まります。

  • /jobsインデックス・ビュー: 最新の10件の仕事を表示します。
  • /jobs/1詳細ビュー: 1というIDを持つ仕事を表示します。

インデックス・ビューも詳細ビューも、jobsアプリケーションの中の、views.pyというモジュールの中に実装されます。このプロジェクトのurls.pyファイルの中で、このコンフィギュレーションを実装すると、次のようになります。

リスト21. urls.pyの中でビューのコンフィギュレーションを実装する
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^admin/', include('django.contrib.admin.urls.admin')),

    (r'^jobs/$', 'djproject.jobs.views.index'),
    (r'^jobs/(?P<job_id>\d+)/$', 'djproject.jobs.views.detail'),
)

<job_id>という部分に注意してください。これは後で重要になります。

ベスト・プラクティスとしては、アプリケーション特有のURLパターンを取り出し、それをアプリケーションそのものの中に置くことです。そうすることによって、プロジェクトからアプリケーションが分離され、再利用がしやすくなります。jobsに対する、アプリケーション・レベルでのURLコンフィギュレーション・ファイルは、次のようなものになります。

リスト22. アプリケーション・レベルでのURLコンフィギュレーション・ファイル、urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^$', 'djproject.jobs.views.index'),
    (r'^(?P<job_id>\d+)/$', 'djproject.jobs.views.detail'),
)

ビュー・メソッドはすべて同じモジュールを元にしているため、最初の引数でモジュールのルート名にdjproject.jobs.viewsを指定することができます。Djangoはそれを使って、indexメソッドとdetailメソッドを探します。

リスト23. jobs/urls.py: indexとdetailを探す
from django.conf.urls.defaults import *

urlpatterns = patterns('djproject.jobs.views',
    (r'^$', 'index'),
    (r'^(?P<object_id>\d+)/$', 'detail'),
)

上記のjobs URLを、全体としてのプロジェクトに結びつけるには、include機能を使います。アプリケーション・レベルのURLは、/jobsセクションの下に結びつけられます。

リスト24. djproject/urls.py: URLをプロジェクトに結びつける
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^admin/', include('django.contrib.admin.urls.admin')),
    (r'^jobs/', include('djproject.jobs.urls')),
)

この時点でテスト・サーバーを使ってインデックス・ページ(http://localhost:8000/jobs)にアクセスしようとすると、エラーになってしまいます。これは、呼ばれているビュー(djproject.jobs.views.index)が、まだ存在していないためです。


ビューを実装する

ビューは単なるPythonメソッドであり、リクエスト・オブジェクトを受け付け、下記に対して責任を持っています。

  • (直接、間接の)すべてのビジネス・ロジック
  • テンプレートに対するデータを持つコンテキスト辞書
  • コンテキストを使ったテンプレートの描画
  • 描画された結果を逆にフレームワークに渡すレスポンス・オブジェクト

Djangoでは、URLがリクエストされた時に呼ばれるPythonメソッドは、『ビュー』と呼ばれます。また、ビューによってロードされ、描画されるページは、『テンプレート』と呼ばれます。そのため、Djangoチームでは、DjangoのことをMVT(model-view-template)フレームワークと呼んでいます。一方TurboGearsでは、自分のメソッドを『コントローラー』と呼び、描画されるテンプレートを『ビュー』と呼ぶため、MVCという略語にぴったりと合います。両者の主な違いは意味体系に関するものであり、得られる結果は同じです。

最も単純なビューでは、ストリングで初期化されたHttpResponseオブジェクトを返します。下記のメソッドを作成し、/jobs HTTPリクエストを行って、urls.pyファイルとviews.pyファイルが正しく設定されることを確認します。

リスト25. jobs/views.py (v1)
from django.http import HttpResponse

def index(request):
    return HttpResponse("Job Index View")

下記のコードは、最新の仕事を少なくとも10件取得し、テンプレートを使ってそれらを描画し、そしてレスポンスを返します。次のセクションで説明するテンプレート・ファイルがないと、これは動作『しません』。

リスト26. jobs/views.py (v2)
from django.template import Context, loader
from django.http import HttpResponse
from jobs.models import Job

def index(request):
    object_list = Job.objects.order_by('-pub_date')[:10]
    t = loader.get_template('jobs/job_list.html')
    c = Context({
        'object_list': object_list,
    })
    return HttpResponse(t.render(c))

上記のコードでは、テンプレートはjobs/job_list.htmlストリングで名前が付けられています。このテンプレートは、object_listという名前のjobリストのコンテキストを使って描画されます。次に、描画されたテンプレート・ストリングはHTTPResponseコンストラクターに渡され、このコンストラクターはフレームワークを通してリクエスト・クライアントに送り返されます。

下記では、テンプレートをロードし、コンテキストを作成し、新しいレスポンス・オブジェクトを返す、というステップが、render_to_responseというコンビニエンス・メソッドで置き換えられています。もう1つ新しいのは、get_object_or_404というコンビニエンス・メソッドを使って(提供された引数を使用して)Jobオブジェクトを取得する、詳細ビュー・メソッドです。このオブジェクトが見つからない場合には、404例外が投げられます。この2つのメソッドによって、多くのWebアプリケーションにありがちな、大量の定型的なコードをなくすことができます。

リスト27. jobs/views.py (v3)
from django.shortcuts import get_object_or_404, render_to_response
from jobs.models import Job

def index(request):
    object_list = Job.objects.order_by('-pub_date')[:10]
    return render_to_response('jobs/job_list.html',
                              {'object_list': object_list})

def detail(request, object_id):
    job = get_object_or_404(Job, pk=object_id)
    return render_to_response('jobs/job_detail.html',
                              {'object': job})

detailがobject_idを引数に取ることに注意してください。この数字は、先ほど触れた、jobsのurls.pyファイルの/jobs/ URLパスの後にあった数字です。この数字はさらに、プライマリー・キー(pk)としてget_object_or_404メソッドに渡されます。

上記のビューがロード、描画するテンプレート(jobs/job_list.htmlと jobs/job_detail.html)はまだ存在していないため、上記のビューは相変わらずフェールします。


テンプレートを作成する

Djangoでは、高速描画と使いやすさを目標に設計された単純なテンプレート言語が用意されています。Djangoのテンプレートは、{{ variables }}と{% tags %}が埋め込まれたプレーン・テキストで作成されます。変数は、それらの変数が表す値を使って評価され、置き換えられます。基本的なコントロール・ロジックには、タグが使われます。テンプレートは、テキスト・ベースのどんなフォーマット(HTMLやXML、CSV、プレーン・テキストなど)の生成にも使用することができます。

最初のステップは、テンプレートがどこにあるかを定義することです。単純にするために、djprojectの下にテンプレート・ディレクトリーを作成し、そのパスをsettings.pyのTEMPLATE_DIRSエントリーに追加します。

リスト28. settings.pyにテンプレート・ディレクトリーを作成する
TEMPLATE_DIRS = (
    '/path/to/devdir/djproject/templates/',
)

Djangoのテンプレートは、『テンプレートの継承(template inheritance)』という概念をサポートしています。サイト設計者は、この概念を使うことによって、テンプレート毎に内容を繰り返さなくても統一的なルック・アンド・フィールを作成することができます。ブロック・タグを持つスケルトン文書、またはベース文書を定義すれば、継承を使用することができます。こうしたブロック・タグには、内容を持つページ・テンプレートが大量に含まれています。下記の例は、titleとextrahead、contentというブロックを持つHTMLスケルトンを示しています。

リスト29. スケルトン文書、templates/base.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Company Site: {% block title %}Page{% endblock %}</title>
    {% block extrahead %}{% endblock %}
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

アプリケーションとプロジェクトの分離を保つために、すべてのJobアプリケーション・ページ・ファイルに対するベースとして、中間的なベース・ファイルを使います。例えばこの例では、単純にするためにアプリケーションのCSSをベース・ファイルに置いています。実際のアプリケーションでは、適切にコンフィギュレーションされたWebサーバーを使ってこのCSSを抽出し、Webサーバーがサービスする静的ファイルの中に置きます。

リスト30. 中間的なベース・ファイル、templates/jobs/base.html
{% extends "base.html" %}

{% block extrahead %}
    <style>
        body {
            font-style: arial;
        }
        h1 {
            text-align: center;
        }
        .job .title {
            font-size: 120%;
            font-weight: bold;
        }
        .job .posted {
            font-style: italic;
        }
    </style>
{% endblock %}

Djangoテスト・サーバーは、デフォルトでは静的ファイルをサービスしません。静的ファイルをサービスするのはWebサーバーの仕事だからです。もし、開発中に画像やスタイルシートなどをDjangoでサービスしたい場合には、この機能をオンするための方法を参考文献のリンクに挙げましたので、それを見てください。

今度は、ビューがロードし、描画する、2つのページ・テンプレートを作成します。jobs/job_list.htmlテンプレートは、インデックス・ビューによるコンテキストから得られる『object_list』に対して単純に繰り返しを行い、それぞれのレコードの詳細ページへのリンクを表示します。

リスト31. templates/jobs/job_list.htmlテンプレート
{% extends "jobs/base.html" %}

{% block title %}Job List{% endblock %}

{% block content %}
    <h1>Job List</h1>
    <ul>
    {% for job in object_list %}
        <li><a href="{{ job.id }}">{{ job.job_title }}</a></li>
    {% endfor %}
    </ul>
{% endblock %}

jobs/job_detail.htmlページは、『job』という1つのレコードを表示します。

リスト32. templates/jobs/job_detail.htmlページ
{% extends "jobs/base.html" %}

{% block title %}Job Detail{% endblock %}

{% block content %}
    <h1>Job Detail</h1>

    <div class="job">
        <div class="title">
            {{ job.job_title }}
            -
            {{ job.location }}
        </div>
        <div class="posted">
            Posted: {{ job.pub_date|date:"d-M-Y" }}
        </div>
        <div class="description">
            {{ job.job_description }}
        </div>
    </div>
{% endblock %}

Djangoテンプレート言語は、限定された機能しか持たないように設計されています。この制約によって、プログラマーではない人にとってはテンプレートが単純になり、またプログラマーが、本来置くべきではない場所(プレゼンテーション・レイヤー)にビジネス・ロジックを置こうとするのを防ぐことができます。テンプレート言語に関するドキュメンテーションへのリンクは、参考文献を見てください。


ジェネリック・ビュー

Djangoには、下記のような典型的なパターンに従ってアプリケーションを作成できるように、4セットの『ジェネリック・ビュー』が付属しています。

  • リスト/詳細ページ・パターンによるビュー(上記の例で示したもの)
  • 日付に基づいてレコードを分類したパターンでのビュー(ニュースやブログのサイトに便利です)
  • オブジェクトのCRUD(creation, update, and deletion)パターンによるビュー
  • 単純な直接テンプレート描画、または単純なHTTPリダイレクト・パターンによるビュー

これによって定型的なビュー・メソッドを作成する必要がなくなり、すべてのビジネス・ロジックはurls.pyファイルの中に置かれ、Djangoが提供するジェネリック・ビュー・メソッドによって処理されるようになります。

リスト33. jobs/urls.pyの中のジェネリック・ビュー
from django.conf.urls.defaults import *
from jobs.models import Job

info_dict = {
    'queryset': Job.objects.all(),
}

urlpatterns = patterns('django.views.generic.list_detail',
    (r'^$', 'object_list', info_dict),
    (r'^(?P<object_id>\d+)/$', 'object_detail', info_dict),
)

このurls.pyファイルは、次の3つの点で大きく変更されています。

  • info_dictマップ・オブジェクトは、アクセス対象Jobに対するクエリー・セットを一緒に渡します。
  • djproject.jobs.viewsではなくdjango.views.generic.list_detailを使っています。
  • 実際に呼ばれるビューは、object_listとobject_detailです。

このプロジェクトは、ジェネリック・ビューへの移行が自動的に行われるように、幾つかの要件に従っています。

  • ジェネリックな詳細ビューでは、object_idという名前の引数を想定しています。
  • テンプレートは、app_label/model_name_list.html (jobs/job_list.html) app_label/model_name_detail.html (jobs/job_detail.html) という命名パターンに従っています。
  • listテンプレートは、object_listという名前のリストを処理します。
  • detailテンプレートは、objectという名前のオブジェクトを処理します。

info_dictを使うと、(1ページ当たりのオブジェクト数を規定する、paginate_byの値など)さらにオプションを渡すことができます。


まとめ

このシリーズの次回の記事では、もう1つのPython Webフレームワークである、TurboGearsに関して解説し、Djangoとの比較を行います。

参考文献

学ぶために

製品や技術を入手するために

  • developerWorksから直接ダウンロードできるIBM ソフトウェア評価版を使って、皆さんの次期Linux開発プロジェクトを構築してください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source, Web development
ArticleID=228095
ArticleTitle=Python Web フレームワーク: 第 1 回 Django と Python を使って Web 開発
publish-date=06062006