Django の概要

Django は変転の激しいニュースルーム環境で開発された経緯から、よくある Web 開発タスクを迅速かつ簡単化するように設計されました。ここでは Django による データベース中心の Web アプリケーション開発をざっと見てみましょう。

このドキュメントの目的は、 Django の技術的な仕様について述べ、どのように動 作するかを理解してもらうことにあり、チュートリアルやリファレンス用ではあり ません。 (とはいえ、チュートリアルもリファレンスも別に用意していますよ!) プロジェクトを作成する準備ができたら、 チュートリアルを始めれます 。もしくは より詳細なドキュメントを読む こともできます。

モデルの設計

データベースなしで Django を使うこともできますが、 Django には Python コードでデータベースのレイアウトを記述した オブジェクトリレーショナルマッパー (object-relational mapper) が付属しています。

データモデル構文 ではモデルを表現するさまざまな方法が提供されています。これまでのところ、長年におけるデータベーススキーマの問題を解決してきた実績があります。 簡単な例を示しましょう:

mysite/news/models.py
from django.db import models

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    def __str__(self):              # __unicode__ on Python 2
        return self.full_name

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

モデルのインストール

次に、データベーステーブルを自動でつくる Django のコマンドラインユーティリティを実行します:

$ python manage.py migrate

migrate コマンドは利用できるモデルを探し出し、テーブルが既に存在していない場合にはデータベースにテーブルを作成し、必要に応じて より強力なスキーマの制御 を提供します。

自動生成される API で楽しむ

これだけで、制約のない充実した Python API を使っ て自分のデータにアクセスできます。API はオンザフライで生成され、コードを作 成する必要はありません:

# Import the models we created from our "news" app
>>> from news.models import Reporter, Article

# No reporters are in the system yet.
>>> Reporter.objects.all()
<QuerySet []>

# Create a new Reporter.
>>> r = Reporter(full_name='John Smith')

# Save the object into the database. You have to call save() explicitly.
>>> r.save()

# Now it has an ID.
>>> r.id
1

# Now the new reporter is in the database.
>>> Reporter.objects.all()
<QuerySet [<Reporter: John Smith>]>

# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'

# Django provides a rich database lookup API.
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter matching query does not exist.

# Create an article.
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# Now the article is in the database.
>>> Article.objects.all()
<QuerySet [<Article: Django is cool>]>

# Article objects get API access to related Reporter objects.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# And vice versa: Reporter objects get API access to Article objects.
>>> r.article_set.all()
<QuerySet [<Article: Django is cool>]>

# The API follows relationships as far as you need, performing efficient
# JOINs for you behind the scenes.
# This finds all articles by a reporter whose name starts with "John".
>>> Article.objects.filter(reporter__full_name__startswith='John')
<QuerySet [<Article: Django is cool>]>

# Change an object by altering its attributes and calling save().
>>> r.full_name = 'Billy Goat'
>>> r.save()

# Delete an object with delete().
>>> r.delete()

作業場 (scaffold) ではなく完成品 (whole house) の、動的な admin インタフェース

モデルを定義したら、 Django は玄人向きの実運用に耐える 管理インタフェー ス を自動的に生成します。 このインタフェースは、認証をパスしたユーザがオブジェクトを追加、変更、削除できる Web サイトです。管理インタフェースの作成は簡単で、モデルクラスを admin サイトに追加するだけです:

mysite/news/models.py
from django.db import models

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
mysite/news/admin.py
from django.contrib import admin

from . import models

admin.site.register(models.Article)

サイトの編集はスタッフ、顧客、もしくはあなた自身の手で行われるものであり、 コンテンツの管理だけのためにバックエンドインタフェースを作りたくはない、という思想がここにはあります。

作者たちが Django アプリケーションを作成するときの典型的なワークフローは、 モデルを作成し、 admin サイトを組み上げてできるだけ早期に立ち上げ、スタッフ (や顧客) がデータを投入できるようにしておいてから、データを公開するための方法を開発してゆくというものです。

URL を設計する

すっきりとして洗練された URL スキームは、高品質な Web アプリケーションを実 現する上で重要な要素です。 Django は美しい URL の設計を助け、 .php.asp のようなお粗末なゴミを URL に入れさせません。

特定のアプリケーション用の URL を設計するには、URLconf と呼ばれる Python モジュールを一つ作成します。 URLconf はいわばアプリケーションの目次にあたり、 URL のパターンを Python のコールバック関数に対応づけています。 URLconf はまた、 URL と Python コードを脱カップリングする働きも持っています。

Reporter/Article の例では、 URLconf は以下のようになります:

mysite/news/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

上のコードはシンプルな:ref:`正規表現 <regex-howto>`と Python のコールバック関数(「ビュー」)をマッピングしています。正規表現は、 URL から値を取得するために括弧を用います。ユーザがページを要求すると、 Django はそれぞれのパターンを順番にチェックし、要求された URL に最初に一致したパターンで停止します。(もしそれらのどれとも一致しなかった時、 Django は特殊ケースである404ビューを呼び出します。)正規表現はロード時にコンパイルされるため、これらは非常に高速に動作します。

正規表現の1つが一致すると、Djangoは与えられたビューを呼び出します。これはPythonの関数です。 各ビューは、リクエストのメタデータを含むリクエストオブジェクトと、正規表現で捉えられた値を渡します。

例えば、ユーザが 「/articles/2005/05/39323/」 という URL をリクエストすると、 Django は news.views.article_detail(request, '2005', '05', '39323') のような関数呼び出しを行います。

ビューの自作

各ビュー (view) には二つの役割があります: 一つはリクエストされたページのコ ンテンツを含む HttpResponse オブジェクトを返すこと、もう一つは Http404 のような例外の送出です。それ以外の処理はユーザ次第です。

一般的に、ビューはパラメーターに従ってデータベースからデータを取り出し、テンプレートをロードして、取り出したデータでテンプレートをレンダリングします。 上の year_archive のビューを例に示しましょう:

mysite/news/views.py
from django.shortcuts import render

from .models import Article

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    context = {'year': year, 'article_list': a_list}
    return render(request, 'news/year_archive.html', context)

この例では Django の テンプレートシステム を使っ ています。テンプレートシステムは、強力な機能をいくつも備えながらも、非プロ グラマが使いこなせる程度に簡単な仕組みです。

テンプレートを設計する

上のコードでは news/article_detail.html という名前のテンプレートをロー ドしています。

Django はテンプレートの重複を最小限にする為に、テンプレートの検索パスを持っています。Djangoの設定ファイルの中で、テンプレートをチェックする DIRS にディレクトリのリストを指定します。最初のディレクトリにテンプレートが存在しかった場合、2番目をチェックし、以降も同様にチェックが続きます。

さて、 news/year_archive.html が見つかったとしましょう。テンプレートは以下のように書かれています:

mysite/news/templates/news/year_archive.html
{% extends "base.html" %}

{% block title %}Articles for {{ year }}{% endblock %}

{% block content %}
<h1>Articles for {{ year }}</h1>

{% for article in article_list %}
    <p>{{ article.headline }}</p>
    <p>By {{ article.reporter.full_name }}</p>
    <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

変数は二重の波括弧で囲まれています。 {{ article.headline }} は、「article の headline という属性の出力」を表しています。とはいえ、ドット表記は属性の検索に使われるだけではありません。辞書の検索や、インデクス指定、関数呼び出しも行えます。

{{ article.pub_date|date:"F j, Y" }} で、 Unix スタイルの「パイプ」 (文字 “|”) を使っていることに注意して下さい。これはテンプレートフィルターと呼ばれ、変数の値にフィルターをかけるためのものです。この例では、フィルタによって Python の datetime オブジェクトを指定の形式にフォーマットしています (PHP の date 関数に似ていますね) 。

フィルターはいくつでも好きなだけ繋げることが出来ます。また、独自の Python コードを実行する カスタムテンプレートフィルタカスタムテンプレートタグ を書くことも出来ます。

最後に、 Django にはテンプレートの継承という概念があります。 継承を宣言しているのは {% extends "base.html" %} の部分です。このタグは「まず ‘base’ というテンプレートをロードせよ。このテンプレートにはいくつかのブロックが定義されているが、それらのブロックの中身を以下のブロック定義で埋めよ」という命令です。要するに、テンプレートを継承すると、各テンプレートごとに固有の定義だけを記述すればよくなり、テンプレート間の冗長性が劇的に減るのです。

ここでよくある“base.html” テンプレートで、 静的ファイルの配信 を含む例をあげます:

mysite/templates/base.html
{% load static %}
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="{% static "images/sitelogo.png" %}" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

このテンプレートはサイトのルック & フィール (とサイトのロゴ) を定義するだけ にまで、極度に単純化されています。また、子テンプレートで埋めるための「穴」 を提供しています。これによって、ベーステンプレート一つを変更するだけでサイ ト全体のデザインを簡単に変更できます。

また、子テンプレートを変えずにベーステンプレートだけを変えた複数バージョン のサイトも作成できます。 Django の作者たちはこのテクニックを使い、新しいテンプレートを作成するだけでモバイル向けのまったく見栄えの違うサイトを作成してきました。

他のシステムを使いたければ、必ずしも Django のテンプレートシステムを使う必 要はないということに注意してください。 Django のテンプレートシステムは Django のモデルレイヤと部分的にしっかり組み合わさっていますが、絶対に使わねばならないということではありません。さらに言えば、 Django のデータベース API を使う必然性もありません。別のデータベース抽象化レイヤを使っても構いま せんし、 XML ファイルやディスク上のファイルを読み込んでも構いません。何でもやりたいことをできるのです。Django の構成要素 – モデル、ビュー、テンプレー ト – は、互いに切り離して利用できるのです。

これらはほんの一部にすぎません

以上、 Django の機能についてざっと紹介してきました。 Django は他にもまだま だ便利な機能を備えています:

  • memcached などのバックエンドを組み込んだ キャッシュフレームワーク
  • 小さな Python クラスを書くだけで簡単に RSS や Atom フィードを生成できる 配信フィードフレームワーク
  • 自動生成される admin のセクシーな機能の数々。ここで紹介したのはほんの表層の一部でしかありません。

次は、あなたが Django をダウンロード して、 チュートリアル を読み、 コミュニティ に参加する番です。ご精読ありがとうございました!

Back to Top