DjangoのcontextとContext Processorsの使い方

Djangoのcontextについてわかりやすく解説します。

DjangoのcontextとContext Processorsの使い方

今回は、Django の『context』という機能について、具体例を交えて解説します。この記事を読み進めることで、contextの使い方、目的や役割について理解することができます。

Djangoのcontextとは?

contextとは、Djangoでテンプレートにデータを渡すための仕組みのことです。contextはPythonの辞書型(dictionary)で表現され、キー(変数名)と値(データ)の組み合わせでデータを保持します。contextを使うことで、ビュー(view)からテンプレートにデータを簡単に渡すことができます。

DjangoでWebアプリケーションを開発する際には、HTMLファイル(テンプレート)にデータを渡す必要があります。例えば、データベースから取得したデータを表示するためには、そのデータをテンプレートに渡します。ここで登場するのが『context』です。

contextの使い方

contextの基本的な使い方について説明します。以下の例では、データベースから取得したデータをcontextを使ってテンプレートに渡しています。Bookモデルから全てのレコードを取得し、それをbooksというキーでcontextに登録しています。そして、render() 関数を使ってテンプレート(book_list.html)にcontextを渡しています。render()関数は、第1引数としてrequestオブジェクト、第2引数としてテンプレート名、第3引数(任意)として辞書型のcontextを受け取ります。

# views.py

from django.shortcuts import render
from .models import Book

def book_list(request):
    books = Book.objects.all()
    context = {
        'books': books,
    }
    return render(request, 'book_list.html', context)

テンプレートでは、{% for %}タグを使ってbooksにアクセスし、各bookの情報を表示しています。contextを使うことで、ビューからテンプレートへ簡単にデータを渡すことができます。

<!-- book_list_html -->

{% for book in books %}
  <div>
    <h2>{{ book.title }}</h2>
    <p>著者: {{ book.author }}</p>
    <p>出版日: {{ book.published_date }}</p>
  </div>
{% endfor %}

これがcontextの基本的な使い方です。

contextに関数やメソッドを登録して、テンプレート内で実行する

contextには変数や値だけではなく、関数を渡すこともできます。条件によってテンプレート上での表示形式を変更したい場合などに便利な使い方です。

以下の例では、テンプレート上で数字の表示形式を変換する関数をcontextに渡して利用しています。

# contextに関数を渡す

def get_formatted_price(price):
    return "${:,.2f}".format(price)

context = {
    'price': 100,
    'get_formatted_price': get_formatted_price,
}
<!-- 渡した関数をテンプレートで使用する -->

<p>価格: {{ get_formatted_price(price) }}</p>

contextに複数のデータをまとめて登録する

contextは辞書型としてデータを登録することができるため、データをネストさせて複数のデータをまとめて扱うことができます。

# 複数のデータをまとめて登録する

context = {
    'user_data': {
        'name': 'Alice',
        'age': 30,
    },
    'book_data': {
        'title': 'Django for Beginners',
        'author': 'John Doe',
    },
}
<!-- ネストさせたデータを扱う -->

<p>ユーザー名: {{ user_data.name }}</p>
<p>年齢: {{ user_data.age }}</p>
<p>書籍名: {{ book_data.title }}</p>
<p>著者: {{ book_data.author }}</p>

get_context_data メソッドとは?

get_context_data()メソッドは、DjangoのClass-based viewsで利用されるメソッドで、テンプレートに渡すcontextを生成するために使用されます。ViewがTemplateViewやListViewなどのClass-based viewsを継承している場合、get_context_data()メソッドをオーバーライドすることで独自のcontextを追加することができます。

以下の例では、HomePageViewがTemplateViewを継承し、get_context_data()メソッドをオーバーライドしています。まず、super().get_context_data(**kwargs) を呼び出して、親クラスのcontextを取得します。次に、独自のcontextとしてwelcome_messageを追加しています。最後に、更新されたcontextを返すことで、テンプレートに渡されます。

from django.views.generic import TemplateView

class HomePageView(TemplateView):
    template_name = "home.html"

    # contextに追加の情報を与える
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['welcome_message'] = "私のサイトにようこそ"
        return context

Context Processorsとは?グローバルで扱うcontextを設定する

Context Processorsとは、Djangoのテンプレートに対してグローバルなcontextを提供する仕組みのことです。これにより、すべてのテンプレートで共通のデータを利用することができます。例えば、ヘッダーやフッターに表示する共通のデータや、ログインしているユーザー情報などをContext Processorsで提供することができます。

DjangoにはデフォルトでいくつかのContext Processorsが用意されており、それらを利用することができます。また、独自のContext Processorsを作成することも可能です。

DjangoのデフォルトのContext Processorsを利用する

Djangoではデフォルトで以下のContext Processorsが用意されています。

  • django.template.context_processors.debug: デバッグ情報を提供
  • django.template.context_processors.request: リクエストオブジェクトを提供
  • django.template.context_processors.media: MEDIA_URL を提供
  • django.template.context_processors.static: STATIC_URL を提供
  • django.template.context_processors.i18n: 翻訳機能に関連する情報を提供
  • django.template.context_processors.tz: タイムゾーンに関連する情報を提供
  • django.contrib.auth.context_processors.auth: 認証に関連する情報(ユーザー情報など)を提供
  • django.contrib.messages.context_processors.messages: メッセージフレームワークに関連する情報を提供

これらのContext Processorsを利用するには、settings.pyのTEMPLATES設定内にあるcontext_processorsオプションに対象のContext Processorsを追加します。

# settings.py

# Djangoが用意しているContext Processorsを利用する
TEMPLATES = [
    {
        # ...
        'OPTIONS': {
            'context_processors': [
                ...
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
            ],
        },
    },
]

独自のContext Processorsを作成する

グローバルでテンプレート内で使いたい変数を作成したい場合には、自分でContext Processorsを作成することもできます。

まず、アプリケーション内にcontext_processors.pyというファイルを作成し、関数を定義します。この関数はリクエストオブジェクトを受け取り、contextの辞書を返す必要があります。

# myapp/context_processors.py

def global_data(request):
    return {
        'site_name': 'Django Sample Website',
        'site_description': 'Djangoで作ったサイトです',
    }

次に、settings.pyのTEMPLATES設定内にあるcontext_processorsオプションに作成したContext Processorsを追加します。

# settings.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...
                'myapp.context_processors.global_data',
            ],
        },
    },
]

これで、独自のContext Processorsが作成され、すべてのテンプレートでsite_namesite_descriptionという変数が利用できるようになります。