DjangoのMTV(Model-Template-View)アーキテクチャにおいて、ビューはリクエストを受け取り、ビジネスロジックを処理した上でレスポンスを返す「制御塔」の役割を果たします。関数として定義されるビューはFBV(Function-Based Views)と呼ばれ、そのシンプルさと直感的な構造から多くのプロジェクトで利用されています。
レスポンスの生成と制御
Djangoでは、
django.httpモジュールに含まれる様々なクラスを使用して、クライアントに返すHTTPレスポンスを制御します。
主要なレスポンスクラスは以下の通りです:
HttpResponse: 標準的なテキストやHTMLを返す(ステータスコード200)
JsonResponse: Pythonの辞書オブジェクトをJSON形式で返す
HttpResponseRedirect / HttpResponsePermanentRedirect: リダイレクト処理(302 / 301)
HttpResponseNotFound: 404エラーを返す
StreamingHttpResponse: 大規模なデータやファイルをストリームとして出力する
以下は、基本的な
HttpResponseの利用例です。
from django.http import HttpResponse
def basic_response_view(request):
html_content = "<html><body><h1>Hello, Django</h1></body></html>"
return HttpResponse(html_content, content_type="text/html", status=200)
renderとredirectによる効率化
文字列でHTMLを構築するのは非効率なため、通常は
renderショートカット関数を使用します。これにより、テンプレートファイルとデータを結合してレスポンスを生成できます。
from django.shortcuts import render
def profile_view(request):
user_data = {'name': 'Taro', 'age': 25}
return render(request, 'user_profile.html', context=user_data, status=200)
リダイレクトについても、
redirect関数を使用することで、URL名やモデルオブジェクトを指定した柔軟な遷移が可能になります。
from django.shortcuts import redirect
def move_to_home(request):
# 名前付きURLへのリダイレクト
return redirect('home_index', permanent=False)
例外レスポンスのカスタマイズ
システムエラーやページ未検出時の挙動をカスタマイズするには、プロジェクトの
urls.pyでハンドラーを指定します。
# urls.py
handler404 = 'myapp.views.custom_404_handler'
handler500 = 'myapp.views.custom_500_handler'
# views.py
def custom_404_handler(request, exception):
return render(request, 'errors/404.html', status=404)
※この設定を有効にするには、
settings.pyで
DEBUG = Falseに設定されている必要があります。
高度なファイルダウンロード機能
Djangoでは、ファイルの提供方法として3つのアプローチがあります。
- HttpResponse: ファイル全体をメモリにロードして返す。小規模なファイル向き。
- StreamingHttpResponse: イテレータを使用してデータを分割して送信する。メモリ消費を抑えられる。
- FileResponse:
StreamingHttpResponseをファイル向けに最適化したもの。
以下に、
FileResponseを用いた実装例を示します。
import os
from django.http import FileResponse, Http404
def secure_file_download(request):
storage_path = "/path/to/files/document.pdf"
if not os.path.exists(storage_path):
raise Http404("ファイルが存在しません")
file_handle = open(storage_path, 'rb')
response = FileResponse(file_handle, as_attachment=True, filename="downloaded_doc.pdf")
return response
HTTPリクエストオブジェクトの解析
ビューの第一引数として渡される
requestオブジェクト(
WSGIRequestクラス)には、クライアントからの全ての情報が含まれています。
よく利用されるプロパティ:
request.method: リクエストの種類('GET', 'POST'など)
request.GET / request.POST: クエリパラメータやフォームデータ
request.FILES: アップロードされたファイルデータ
request.headers: HTTPヘッダー情報
request.user: 現在ログイン中のユーザーオブジェクト
def inspect_request(request):
print(f"アクセス元ホスト: {request.get_host()}")
print(f"プロトコル: {request.scheme}")
if request.method == 'GET':
query = request.GET.get('search_word', '')
return HttpResponse(f"検索ワード: {query}")
ファイルのアップロード処理
フォームを介して送信されたファイルは、
request.FILES経由でアクセスします。HTML側で
enctype="multipart/form-data"を指定することが必須です。
# views.py
def upload_handler(request):
if request.method == 'POST' and request.FILES.get('attachment'):
target_file = request.FILES['attachment']
# 保存先パスの設定
save_path = os.path.join('uploads', target_file.name)
with open(save_path, 'wb+') as destination:
# チャンクごとに処理することでメモリ効率を維持
for chunk in target_file.chunks():
destination.write(chunk)
return HttpResponse("アップロード完了")
return render(request, 'upload_form.html')
InMemoryUploadedFile(小規模ファイル)または
TemporaryUploadedFile(大規模ファイル)として扱われるため、
chunks()メソッドを使用して保存することで、サーバーのメモリ負荷を最小限に抑えることができます。