〰️

Djangoでフォーム送信後に遷移したページでブラウザリロードをしたときにフォームの再送信をしないようにする

2024/09/20に公開

Djangoを使ったWebアプリを作っている時に、Form送信後のページでブラウザリロードしたらフォーム再送信の警告が出てしまい解決するのに微妙に悩んだので備忘として書いておく。
(これまでdjangorestframeworkを使うことが多かったので今更な感じですね...)

結論

PRGパターン(Post Redirect Get)に沿ってフォーム送信後の処理の終わりで遷移先のページにRedirectしてあげればいいらしい。
つまり、OKパターンのような処理の流れにすればいい。
NGパターンだとブラウザリロードをするとフォームを再送信してしまう。

OKパターン

  1. POST(フォームの送信)
  2. Redirect(フォーム送信後のページへのリダイレクトを返す)
  3. GET(フォーム送信後のページへ遷移)

NGパターン

  1. POST(フォームの送信)
  2. GET(フォーム送信後のページへ遷移)

サンプルコード

以下は関数ベースビューを使ったOKパターンとNGパターンのサンプルコードです。
POSTされた最後の処理でredirectするかrenderするかの違いがあります。
POSTの処理をした後に、遷移先のページにredirectすると遷移先でブラウザリロードしてもフォームを再送信しません。

from django.shortcuts import render, redirect

def ok_index(request):
    if request.method == "POST":
        print("POSTされたよ!")
        # redirectしてあげることでブラウザリロードしてもフォームを再送信しない
        return redirect("prgapp:ok_page")

    return render(request, "prgapp/ok_index.html")


def ng_index(request):
    if request.method == "POST":
        print("POSTされたよ!")
        # renderにするとブラウザリロードした時にフォームを再送信のメッセージがでる
        return render(request, "prgapp/ng_index.html")

    return render(request, "prgapp/ng_index.html")

Discussion