DjangoのcontextとContext Processorsの使い方
Djangoのcontextについてわかりやすく解説します。
今回は、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_name
とsite_description
という変数が利用できるようになります。