DjangoのMTV(Model-Template-View)フレームワークにおいて、ビュー層はアプリケーションのロジックを制御し、テンプレート層はユーザーに表示するインターフェースを管理します。本記事では、これらの役割と具体的な実装方法について解説します。
Djangoのビュー層(Views)
ビュー(View)は、Webリクエストを受け取り、Webレスポンスを返すPythonの関数またはクラスです。レスポンスには、HTMLコンテンツ、リダイレクト、404エラー、XMLドキュメント、画像などが含まれます。
FBV(関数ベースビュー)とCBV(クラスベースビュー)
Djangoでは、関数としてビューを定義するFBVと、クラスとして定義するCBVの2種類の実装方法があります。
CBVの例:from django.views import View
from django.http import HttpResponse
from django.shortcuts import render
class UserRegistrationView(View):
def dispatch(self, request, *args, **kwargs):
# 処理前の共通ロジック
return super().dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, 'register.html')
def post(self, request):
username = request.POST.get('username')
return HttpResponse(f'User {username} registered successfully.')
URL設定(urls.py)では、クラスに対して .as_view() を呼び出します。
path('register/', UserRegistrationView.as_view()),
FBVの例:
from django.http import HttpResponse
import datetime
def system_status(request):
current_time = datetime.datetime.now()
message = f"現在の時刻は {current_time} です。"
return HttpResponse(message)
HttpRequestオブジェクト
ビューの第一引数として渡される request オブジェクトには、リクエストに関する詳細情報が含まれています。
- request.method: HTTPメソッド('GET' や 'POST' など)。
- request.GET / request.POST: 送信されたパラメータを含む辞書ライクなオブジェクト。
- request.FILES: アップロードされたファイル情報。
- request.user: 現在ログインしているユーザー情報。
- request.path: リクエストされたページのフルパス。
レスポンスの種類
- HttpResponse: 文字列やデータを直接返します。
- render: テンプレートファイルとデータを組み合わせてHTMLを生成します。
- redirect: 別のURLへ転送します。
from django.shortcuts import render, redirect
def profile_view(request):
if not request.user.is_authenticated:
return redirect('/login/')
user_data = {"name": "田中", "role": "管理者"}
return render(request, "profile.html", user_data)
テンプレート層(Templates)
テンプレートは、HTMLの中にDjango独自のテンプレートタグや変数を埋め込んだものです。
変数の表示
二重の中括弧 {{ variable }} を使用して値を表示します。ドット記法で辞書のキー、属性、メソッド(引数なし)にアクセス可能です。
<p>名前: {{ user.name }}</p>
<p>役割: {{ user.role.upper }}</p>
<p>リストの最初の要素: {{ items.0 }}</p>
フィルター(Filters)
パイプ記号 | を使って変数を加工します。
- default:
{{ value|default:"データなし" }} - length:
{{ my_list|length }} - date:
{{ current_date|date:"Y年m月d日" }} - safe: HTMLエスケープを無効化します。
テンプレートタグ(Tags)
ロジック(繰り返しや条件分岐)を記述します。
条件分岐:{% if score >= 80 %}
<p>合格です!</p>
{% elif score > 50 %}
<p>追試対象です。</p>
{% else %}
<p>不合格です。</p>
{% endif %}
繰り返し:
{% for member in members %}
<li>{{ forloop.counter }}: {{ member.name }}</li>
{% empty %}
<p>メンバーはいません。</p>
{% endfor %}
カスタムタグとフィルター
独自ロジックをテンプレートで使いたい場合、templatetags ディレクトリを作成して定義します。
# app/templatetags/custom_filters.py
from django import template
register = template.Library()
@register.filter
def multiply_by(value, arg):
return value * arg
@register.simple_tag
def get_welcome_msg(name):
return f"ようこそ、{name}さん!"
テンプレートでの利用方法:
{% load custom_filters %}
{{ price|multiply_by:1.1 }}
{% get_welcome_msg "佐藤" %}
テンプレートの継承
共通のレイアウトを定義し、各ページで必要な部分だけを上書きする仕組みです。コードの重複を避けるために不可欠です。
ベーステンプレート (layout.html):<html>
<head>
<title>{% block title %}マイサイト{% endblock %}</title>
</head>
<body>
<nav>メニュー</nav>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
子テンプレート:
{% extends "layout.html" %}
{% block title %}プロフィールページ{% endblock %}
{% block content %}
<h1>プロフィール詳細</h1>
<p>ここに内容が入ります。</p>
{{ block.super }} {# 親ブロックの内容も保持したい場合 #}
{% endblock %}