概要
本記事作成の経緯
趣味でWEBアプリを作成する際、「ログイン無しでの気軽な削除機能を実装したい!」「でも、好き勝手に削除されると困る!」と言う状況が発生し、パスワード(合言葉)を用いた削除機能について色々と検索してみたのですが、ズバリこれという物が見つからなかったので、不細工な例でも無いよりマシか?と思い、本記事を作成しました。
(もし上質な上位互換記事が存在し、検索汚染になってしまっていたらすいません)
本記事で紹介するものの説明
簡潔に言うと:削除確認画面で合言葉を入力し、それが正しいものであれば削除を行います。間違っていればその旨を表示します。
Djangoの汎用削除ビュー:DeleteViewを基本的に使い回しながら、メソッドをオーバーライドすることで実装していきます。本記事では、viewと 削除確認画面template内の記述について、本削除機能に関係あるものだけを抜粋して紹介します。
全体像はGitHubに公開してあるので、もしよろしければそちらも参照してください。
(リンク先及び当記事に記載されたコードは、コーヒーの味に対する投票を行うアプリに関するものです)
コード例
viewの一部
from django.urls import reverse_lazy
from django.views import generic
from django.shortcuts import get_object_or_404,render
from .models import Coffee,Voting
class DeleteView(generic.edit.DeleteView):
model = Coffee
success_url = reverse_lazy('coffee_voting:index')
#合言葉の判定はここ以降
def dispatch(self, request, *args, **kwargs):
if request.POST: #POSTがあったときのみ合言葉をチェック
obj = request.POST['delete_pass']
if obj!='goma': #入力された合言葉が正しいか判断(今回の場合、正解合言葉はgoma)
context={
'coffee': get_object_or_404(Coffee, pk=self.kwargs.get('pk')),
'error_message':'あいことばが違います'
}
return render(self.request,'coffee_voting/coffee_confirm_delete.html',context)
return super(DeleteView, self).dispatch(request, *args, **kwargs)
削除確認画面template(coffee_confirm_delete.html)の一部
<p>'{{ coffee.brand }}'を削除しますか?</p>
<!--合言葉入力フォーム -->
<form action='' method='post'>{% csrf_token %}
あいことば:<input type='text' name='delete_pass'>
<button type='submit'>削除する</button>
</form>
<!--合言葉が間違っていれば表示-->
{% if error_message %}
<p class=error-message>⚠エラー:{{error_message}}</p>
{% endif %}
注意:もっと良い方法があると思います......
これはあくまで自分が「とりあえず動く~」で作成したものなので、あまり参考にしてはいけない点が多くあると思います。
問題点の例
- POSTメソッドでrender()メソッドを呼ぶのは避けた方がいい
(参考:【Django】FormViewでPOST時のリダイレクト動作を任意に変える方法)
この例ではform_validで最終的にrender()メソッドを呼び出していますが、実際はPOSTでrender()メソッドを呼ぶのは避けた方がいいです。理由は、POSTした後にブラウザの「戻る」や「再読み込み」をするときにPOSTの再送信が行われるためです(ブラウザからエラーも表示されます)。これを防ぐために、基本的にPOST時にはrender()メソッドではなくredirect()などでGETページへリダイレクトすることを推奨します。
(ただしリダイレクトではコンテキスト情報を渡すことができないので、データをモデルに登録するなどしてGETでもデータを取得できるようにする必要があります)
このほかにも様々な問題点を抱えている、スマートでないコードだと思います。そのため、本記事だけでなく様々な記事を参照することをお勧めします。
本記事は以上となります。ここに記載された内容が、少しでも読んだ方のお役に立てたなら嬉しいです。