質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Q&A

1回答

2513閲覧

djangoで二重送信制御

sususu

総合スコア99

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

0グッド

0クリップ

投稿2020/05/26 14:37

編集2020/05/28 09:37

djangoの初心者です。
どなたかご教授頂ければ幸いです。

教えていただきたい事はWEBアプリでの二重送信制御についてです。
ボタンを複数回押してしまうとサーバに重複したデータが送信されてしまうと思うのですが、djangoで作成する場合どのように制御していますでしょうか。

質問1.何かミドルウェアやライブラリ的なものはありますでしょうか。なにか皆様が実装している良い方法などあれば教えていただきたいと思っております。

質問2.次のようなサイトを発見したのですがこれを実装する場合下記の通り実装しないといけないのでしょうか?
(A)submitがあるページを返すdefにはすべてtokenを取得させるコードを追加
(B)submitボタンが押された後に実行されるdefすべてにtokenをチェックさせるコードを追加
https://qiita.com/hamemi/items/d6cb8e0d60821a7e89aa

質問ばかりで申し訳ありませんがどなたかご教授頂ければ幸いです。
よろしくお願いいたします。

下記の通りに修正しましたが、ボタンを連打すると、複数回インサートが実行されてしまいます。
--追記--

@require_POST @login_required def create_thread(request): if request.method == 'POST': form = ThreadForm(request.POST) if form.is_valid(): thread = form.save(commit=False) thread.user = request.user thread.save() messages.success(request, "投稿が完了しました!") form = ThreadForm() else: form = ThreadForm() return redirect('app:display_threads')

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ForestSeo

2020/05/26 20:57 編集

送った後もformに文字が残り、連打したら何回も送れるのを防ぐこと でいいですか? あと、views.pyは関数かクラスのどちらでやっていますか?
sususu

2020/05/26 23:01

いつもご返信ありがとうございます。 はい、連打での送信が防げればと思います。 いまは一応関数ベースでやっております。 よろしくお願いします。
guest

回答1

0

返信した後に、入力値が残るということは、POST送信時の動作で

Python

1if request.method == 'POST' 2 form = ~~Form(request.POST) 3```このようにしてませんか?これを 4```Python 5if request.method == 'POST' 6 form = ~~Form() 7```にすれば、送った時書いていたものが消えます。 8 9---追記--- 10```Python 11def create_thread(request): 12 if request.method == "POST": 13 form = ThreadForm(request.POST) 14 if form.is_valid(): 15 thread = form.save(commit=False) 16 thread.user = request.user 17 thread.save() 18 messages.success(request, "投稿が完了しました!") 19 form = ThreadForm() 20 else: 21 form = ThreadForm() 22 return redirect('app:display_threads') 23```普通request.method == "POST"で分岐すると思うのですが...

投稿2020/05/27 03:29

編集2020/05/28 21:27
ForestSeo

総合スコア2720

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sususu

2020/05/27 09:56

ご回答ありがとうございます。 リクエストを送るときに、フォームに値を入れてインサートしております。 コードは下記の通りです。 「request.POST」を取ったら、入力値がインサートされなくなってしまいました。 def create_thread(request): form = ThreadForm(request.POST) if form.is_valid(): thread = form.save(commit=False) thread.user = request.user thread.save() messages.success(request, "投稿が完了しました!") return redirect('app:display_threads') ボタンを押すと上記の関数が働くのですが、ボタンを連打すると同じレコードがインサートされてしまう状況です。 お手数おかけしますがご確認よろしくお願いいたします。
ForestSeo

2020/05/27 10:00

追記しました。
sususu

2020/05/27 10:37

ご回答ありがとうございます。 投稿でしか使用しない関数だったのでrequire_postで制御していたのですが、ご教授頂いた通りPOSTとGETの分岐を指定いたしました。 しかしインサートがされなくなってしまいました。 「request.POST」がない場合はどのようにしてテンプレートの入力値を取得しているのでしょうか。 質問ばかりで申し訳ございませんがよろしくお願いいたします。
ForestSeo

2020/05/27 10:51

あっそうですねすみません。 formに何も入ってなかったらvalidできませんね。追記しました
sususu

2020/05/27 14:49 編集

追記させて頂きました。 またご教授頂いた通りに修正してみたつもりなのですが、中身が空になってしまいます。 またボタンを連打すると多重でリクエストが送られているみたいで複数のスレッド情報がインサートされてしまう状況です。 引き続き調査いたします。
ForestSeo

2020/05/27 20:17

何回もすみません。 form.is_validのあとにformを初期化していたので、編集しました。
sususu

2020/05/28 09:40

こちらこそ何度も申し訳ございません。 再度修正したコードを記載いたしました。しかしサーバーからレスポンスが帰ってくるまでにボタンを連打すると複数のデータがインサートされてしまう状態です。
ForestSeo

2020/05/28 10:20 編集

うーん POST後にredirectすれば良いんじゃないでしょうか。 というか何も入力せずに送れるんですか?
sususu

2020/05/28 12:53

何度もコメントして頂いてありがとうございます。 一応modelsの方でnullとblankを制御しているので、未入力はボタンが押せないような状態となっています。
ForestSeo

2020/05/28 21:27

そうですよね。 今追記したのでいけると思います。
sususu

2020/05/30 13:21

返事が遅くなってしまい申し訳ありません。 追記させて頂きました。 ご教授頂いた通りに修正したつもりですが、未だに多重送信されており、データベースに複数回インサートが行われている状態です。
sususu

2020/05/30 13:21

念のためこちらにもコードを記載しておきます。 def create_thread(request): if request.method == 'POST': form = ThreadForm(request.POST) if form.is_valid(): thread = form.save(commit=False) thread.user = request.user thread.save() messages.success(request, "投稿が完了しました!") form = ThreadForm() else: form = ThreadForm() return redirect('app:display_threads')
sususu

2020/06/02 23:53

いろいろご教授頂きまして有難うございました。 私の環境などに何か問題があるかもしれません... 今回はとりあえずsessionのtokenを確認する下の方法で実装したいと思います。 https://qiita.com/hamemi/items/d6cb8e0d60821a7e89aa
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問