ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
redirect() の 3 つの渡し方
from django.shortcuts import redirect
# 1. URL 名(推奨)
return redirect("blog:index")
return redirect("blog:detail", pk=article.pk)
# 2. モデルインスタンス(get_absolute_url が呼ばれる)
return redirect(article)
# 3. URL 文字列
return redirect("/blog/")
return redirect("https://example.com/")
URL 名で書けば、ルーティングを変えてもビューを直す必要がありません。urls.py の name= の付け方は aタグのhrefの記載方法 と同じ仕組みです。
POST の後は必ずリダイレクト
from django.contrib import messages
from django.shortcuts import redirect, render
def create(request):
if request.method == "POST":
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save()
messages.success(request, "登録しました")
return redirect("blog:detail", pk=article.pk) # ← ここが重要
else:
form = ArticleForm()
return render(request, "blog/create.html", {"form": form})
保存後に render() で画面を返すと、ブラウザの再読み込みで同じ POST が再送されます。「登録ボタンを 1 回押したのに 2 件登録された」の典型的な原因です。
この「POST → Redirect → GET」の流れを PRG パターンと呼びます。バリデーションエラーのときだけ render() で戻し、成功時は必ずリダイレクトします。
クエリ文字列を付ける
from urllib.parse import urlencode
from django.urls import reverse
url = reverse("blog:index") + "?" + urlencode({"page": 2, "q": "検索語"})
return redirect(url)
redirect("blog:index", page=2) と書いても ?page=2 にはなりません。URL のパス部分の引数として解釈されるため、該当する path() が無ければ NoReverseMatch になります。
ステータスコードの違い
| コード | 意味 | Django での書き方 |
|---|---|---|
| 302 | 一時的(既定) | redirect(...) |
| 301 | 恒久的な移転 | redirect(..., permanent=True) |
| 303 | POST の後は GET で取り直せ | HttpResponseSeeOther |
| 307 / 308 | メソッドを変えずに転送 | 通常は使わない |
301 はブラウザに強くキャッシュされます。一度返すと、設定を戻してもユーザーの手元では古い転送先が使われ続けます。検索エンジンに移転を伝える目的以外では 302 を使ってください。
ログイン後に元のページへ戻す
from django.shortcuts import redirect
from django.utils.http import url_has_allowed_host_and_scheme
def login_view(request):
if request.method == "POST":
# ... 認証処理 ...
next_url = request.POST.get("next") or request.GET.get("next")
if next_url and url_has_allowed_host_and_scheme(
next_url,
allowed_hosts={request.get_host()},
require_https=request.is_secure(),
):
return redirect(next_url)
return redirect("home")
検証せずに redirect(request.GET["next"]) と書いてはいけません。攻撃者が ?next=https://evil.example/ を仕込んだリンクを配ると、自サイトのログインを経由して偽サイトへ誘導できてしまいます(オープンリダイレクト)。
クラスベースビューの場合
from django.urls import reverse_lazy
from django.views.generic import CreateView, RedirectView
class ArticleCreateView(CreateView):
model = Article
fields = ["title", "body"]
success_url = reverse_lazy("blog:index") # 固定の遷移先
# 動的に決めたいときはこちら
def get_success_url(self):
return reverse("blog:detail", kwargs={"pk": self.object.pk})
class OldPageView(RedirectView):
pattern_name = "blog:index"
permanent = True
クラス属性で URL を組み立てるときは reverse_lazy を使います。reverse だとモジュール読み込み時に評価され、URL 設定がまだ読まれていないため ImproperlyConfigured になります。
model に get_absolute_url() が定義されていれば success_url は省略できます。
そのほかのリダイレクト
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
return HttpResponseRedirect("/blog/") # redirect() の中身はこれ
return HttpResponsePermanentRedirect("/blog/") # 301
# 直前のページへ戻す(Referer が無い場合に備えて既定値を用意する)
return redirect(request.META.get("HTTP_REFERER", "/"))
HTTP_REFERER は送られてこないことがあり、値も偽装できます。遷移先の決定に使う場合も、前節と同じ検証を通してください。
うまくいかないとき
| 症状 | 原因 |
|---|---|
| リダイレクトされない | redirect(...) を return していない |
NoReverseMatch | URL 名・名前空間・引数が合っていない |
ERR_TOO_MANY_REDIRECTS | 転送先が自分自身を指している。条件分岐を見直す |
| 末尾スラッシュで 1 回余分に転送される | APPEND_SLASH の働き。path() の定義に合わせる |
| 301 が消えない | ブラウザのキャッシュ。シークレットウィンドウで確認する |
| messages が表示されない | 遷移先のテンプレートで {% for m in messages %} を出していない |
関連
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- 【django】ログイン 認証機能 2026-09-08 03:22:09
- MySQL ERROR 1063 Incorrect column specifier for column|原因と直し方 2026-09-08 03:11:09
- 【PHPエラー】Object of class stdClass could not be converted to string 2026-09-07 07:46:04
- Julia Genie ローカル開発サーバ起動完全ガイド 2026-09-07 07:46:04
- Wi-Fi とは|規格と世代(Wi-Fi 4〜7)・周波数帯・CSMA/CA・WPA3 NEW 2026-09-07 07:45:13
- set コマンドでシェルオプションと位置パラメータを操作 | bash 2026-09-07 07:45:13
- JPEG(.jpg/.jpeg)画像形式の完全ガイド — 仕様・マジックナンバー・他形式との比較・EXIF 2026-09-07 07:45:13
- UE5 Get Overlapping Actorsで特定クラスだけ処理|Class Filter・Cast To 2026-09-07 07:45:13
- Linuxで特定拡張子のファイルを再帰削除|find -deleteの安全手順 2026-09-07 07:45:13
- Django CBVでテンプレートに値を渡す|get_context_data・extra_context 2026-09-07 07:45:13
- Linuxで複数ファイルの文字列を一括置換|find・sed・xargsの安全手順 2026-09-07 07:45:13
- Laravelルートグループ|prefix・middleware・nameで一括管理 2026-09-07 07:45:13
- Linux whichコマンドの使い方|絶対パス取得とtype・command -vの違い 2026-09-07 07:45:13
- Linux catコマンドの使い方|行番号表示・複数ファイル連結 2026-09-07 07:45:13
- unable to execute 'gcc': No such file or directory 2026-09-07 07:45:13
コメントを削除してもよろしいでしょうか?