# Django 5.2.8 ドキュメント

# Django の概要

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

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

## モデルの設計

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

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

`news/models.py`

    from django.db import models

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

        def __str__(self):
            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):
            return self.headline

## モデルのインストール

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

/ 

    $ python manage.py makemigrations
    $ python manage.py migrate

    ...\> py manage.py makemigrations
    ...\> py manage.py migrate

`makemigrations` コマンドは、利用できるモデルを全て見て、まだ作成されていないテーブルを作るためのマイグレーションを生成します。`migrate` コマンドは、マイグレーションを実行し、実際にデータベースにテーブルを作成します。また、必要に応じて、より強力にスキーマを制御する 機能も提供します。

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

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

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

    # 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 は自動的にプロ仕様の本番仕様の 管理インターフェース -- 認証されたユーザがオブジェクトを追加、変更、削除できるウェブサイトを作成できます。必要なステップは、管理サイトにモデルを登録することだけです。:

`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)

`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 は以下のようになります:

`news/urls.py`

    from django.urls import path

    from . import views

    urlpatterns = [
        path("articles/<int:year>/", views.year_archive),
        path("articles/<int:year>/<int:month>/", views.month_archive),
        path("articles/<int:year>/<int:month>/<int:pk>/", views.article_detail),
    ]

上のコードは、 URL パスを Python のコールバック関数("views")にマッピングしています。 パス文字列は、パラメータタグを使用して URL から値を取得します。 ユーザがページをリクエストすると、Django は各パスを順番に実行し、要求された URL に最初に一致したパスで停止します。 (それらのどれとも一致しない場合、Django は特殊なケースである404ビューを呼び出します。)パスはロード時に正規表現にコンパイルされるので、これらは非常に高速に動作します。

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

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

## ビューの自作

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

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

`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/year_archive.html` という名前のテンプレートをロードしています。

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

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

`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” テンプレートで、 静的ファイルの配信 を含む例をあげます:

`templates/base.html`

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

簡単に言えば、サイトのルックアンドフィール（サイトのロゴ）を定義し、子テンプレートが埋めるための「穴」を提供します。つまり、サイトの再設計は、ベーステンプレートという1つのファイルを変更するだけで行うことができます。

また、子テンプレートを再利用しながら、異なるベーステンプレートで複数のバージョンのサイトを作成することもできます。Django の作者はこのテクニックを使って、新しいベーステンプレートを作成するだけで、印象的に異なるモバイルバージョンのサイトを作成しています。

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

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

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

- memcached などのバックエンドを組み込んだ キャッシュフレームワーク 。

- Pythonの小さなクラスを書くことでRSSやAtomフィードを作成できる 配信 (syndication) フレームワーク 。

- 自動生成される admin の魅力的な機能の数々。ここで紹介したのはほんの表層の一部でしかありません。

次のステップは Django をダウンロードし、 チュートリアル を読み、 コミュニティに参加する ことです。ご興味を持っていただきありがとうございました。