本文へスキップ
BecomeCoder

Djangoコース · 第2章 URLとビュー · レッスン9

ステータスコードとリダイレクト

ブラウザで完結

導入

Web の返事には、本文だけでなく「ステータスコード」という3桁の数字が必ず付きます。200(成功)、404(見つからない)、302(別の URL へ移動)など。これを正しく使うのがプロの Web アプリです。

説明

代表的なステータスコードは次の通りです。

コード意味
200OK(成功)
302リダイレクト(別の URL へ移動してね)
404Not Found(見つからない)
500サーバー内部エラー

Django では次のように扱います。

import django
from django.conf import settings
if not settings.configured:
    settings.configure(DEBUG=True, SECRET_KEY="dev",
        ROOT_URLCONF=__name__, ALLOWED_HOSTS=["testserver"])
    django.setup()

from django.http import HttpResponse, HttpResponseNotFound, Http404
from django.shortcuts import redirect
from django.urls import path

users = {1: "Aki", 2: "Bob"}

def profile(request, id):
    if id not in users:
        raise Http404("ユーザーが見つかりません")   # 404 を返す
    return HttpResponse(f"プロフィール: {users[id]}")

def old_top(request):
    return redirect("/")           # 302 で / へ移動

def home(request):
    return HttpResponse("新トップ")

urlpatterns = [
    path("", home),
    path("users/<int:id>/", profile),
    path("old/", old_top),
]

from django.test import Client
client = Client()
print("200?", client.get("/users/1/").status_code, client.get("/users/1/").content.decode())
print("404?", client.get("/users/999/").status_code)
r = client.get("/old/")
print("302?", r.status_code, "->", r["Location"])  # 302 -> /
  • raise Http404(...) … データが無いときに 404 を返す定番。DEBUG=True だと詳細ページ、本番だと 404 ページが表示されます。
  • redirect("/") … 302 レスポンスを返し、ブラウザを別 URL へ飛ばします。フォーム送信後に一覧へ戻すときの定番です。移動先は返り値の Location ヘッダに入ります。

やってみよう

client.get("/users/2/") は 200、client.get("/users/5/") は 404 になります。/old/ にアクセスすると 302 で / に飛ばされることを確かめましょう。

演習

/go-home/ にアクセスすると / へリダイレクトするビュー go_home を作ってください。r = client.get("/go-home/") として print(r.status_code, r["Location"]) で確認します(302 / になれば成功)。

ヒント1を見る

def go_home(request): return redirect("/")

ヒント2を見る

path("go-home/", go_home) を登録します。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。