Django Tutorial Part 8 -- データがない時に 404 のページを出すようにする
kaede
Posted on April 17, 2022
何をするか
https://docs.djangoproject.com/en/4.0/intro/tutorial03/#raising-a-404-error
polls/views.py/detail で URL から渡された id のデータがない時に 404 のページを返すようにする。
現状存在しない id で detail を見るとどうなるか
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
現状は、request として URL から渡された question_id をそのまま ページで表示することになっている
よって、存在しない id でもエラーが出ない。
question id に基づく question と detail.html を読み込むようにする。
def detail(request, question_id):
question = Question.objects.get(pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
ここから question_id に基づいてテーブルのレコードを取ってきて
polls/template/polls/detail.html を読み込み、context として question を渡すようにする
<h1>Question Detail</h1>
<h2>Question Text</h2>
{{ question }}
そしてファイルを作成すると、detail で id に基づいた question_text が読める。
try except raise 無しで存在しない question_id にアクセスする
これでは try except を書いていないので、データがない question_id
にアクセスすると DoesNotExist at /polls/5/
のエラーページが出てしまう
Http404 を使って Question.DoesNotExist で 404 とエラーの詳細を表示する
from django.http import HttpResponse, Http404
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
Http404 のライブラリをインポートして
try に先ほどの処理を書いて
except で Question.DoesNotExist の条件で
Http404 と raise で
その Question のレコードがないと言うメッセージを返す。
これでレコードがない question_id にアクセスすると
404 と表示して、詳細なエラーの原因を表示できるようになる。
ここに 404 Page として HTML も設定できるのだろうか?要検証
GitHub の 404 は可愛い。
get_object_or_404 を使って try except を省略して処理を書く。
https://docs.djangoproject.com/en/4.0/intro/tutorial03/#a-shortcut-get-object-or-404
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
この正常と例外に分かれているコードを
question = get_object_or_404(Question, pk=question_id)
この一行で同じようにかける。
Question.DoesNotExist の条件や、Question does not exist のメッセージは詳しく指定できないが
No Question matches the given query.
(question_id = 5 と言う) クエリにマッチした Question が見つからなかったと言うメッセージで返してくれる。
try と except で書いた方が丁寧で正確だと思うが、
手早く書くならこれでもありだと思った。
まとめ
def detail(request, question_id):
question = Question.objects.get(pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
TableName.objects.get でレコードを取ってくるときは、
中身がないと DoesNotExist のエラーがそのまま出る
try-except raise で
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
Http404 を使えば
条件に応じた例外処理とエラーメッセージで
404 のページが出せる。
question = get_object_or_404(Question, pk=question_id)
get_object_or_404 を使うとレコードがなかったときに、
query にマッチしなかったと言うメッセージで 404 のページが出せる。
Posted on April 17, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.