【Django】get_object_or_404の書き方|実例付

※本サイトにはプロモーション・広告が含まれています。

(最終更新月:2021年11月)

✔当記事はこのような方に向けて書かれています

「Djangoで404ページの作り方が知りたい」

「objects.get()で、対象のレコードがないときはどうすれば良い?」

「Webアプリの公開に向けてより実践的な機能を実装したい」

✔当記事を通じてお伝えすること

  • 404ページを表示するための「get_object_or_404」メソッドの使い方

当記事をご覧いただければ、get_object_or_404の書き方はもちろん、404ページの必要性までご理解いただけます。

ぜひ最後までご覧ください。

✔YouTube解説動画

当記事の内容は動画を見ながら進めると、約15分程度で完了します。

動画ならではの情報も解説しているので、記事と一緒にご覧ください。

動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

今のままだとダメなの?

現況だと、ディーテイルビューやアップデートビューでは、URLで「pk」を受け取り、対象のデータをデータベースから取得するよう記述しています

変数名 = NippoModel.objects.get(pk=pk)

仮に「pk」が存在しない値でアクセスを試みると、

localhost:8000/nippo/update/100/

※「pk」を100としアクセスを試みます(データとして存在しない値であれば何でも良いです!)

対象の「query」が存在ないというエラーになります

ターミナルでは、

"GET /nippo/update/100/ HTTP/1.1" 500 73186

となっています

これは、URLの入力というリクエストに対して、サーバー側からのレスポンスのステータスが「500」ということを意味しています

ステータス「500」というのは、サーバーに関する様々なエラーを指しているためWebで公開後環境で起こるエラーの原因が特定できないためとても不便です

つまり、開発中のローカル環境で出てくる分には気になりませんが、公開後を考えると修正する必要があるということになります

それでは通常、存在しないページへアクセスするとどんなページ、レスポンスが返ってくるのでしょうか?

当ブログで存在しないURLを打ち込んでみましょう

itc.tokyo/something-wrong-url/

というページが返ってきます

これは、ステータス404という「ページが見つからない」時に出てくるステータスコードです

これだと「ページが見つからない!」ということがはっきりわかりますので、当アプリでもステータス404を返すように設定していくことが重要になります

【ステータス404を返す】get_object_or_404

get_object_or_404は以下のように書きます。

get_object_or_404(クラス名, 引数)

仕組みはこうなります。

  • 対象のオブジェクトを取得する
  • 取得できない場合は404ページを返す

実際のコードを見ていきましょう!

【実例紹介】日報アプリに使ってみよう!

何はともあれまずはメソッドをインポートしましょう

from django.shortcuts import render, get_object_or_404

nippoDetailView関数、nippoUpdateForm関数内で下記の記述を変更していきましょう

オブジェクト変数 = NippoModel.objects.get(pk=pk)

を、

オブジェクト変数 = get_object_or_404(NippoModel, pk=pk)

へ変更していきます

✔ディテールビュー:nippoDetailView関数

def nippoDetailView(request, pk):
    template_name = "nippo/nippo-detail.html"
    ctx = {}
    q = get_object_or_404(NippoModel, pk=pk)
    ctx["object"] = q
    return render(request, template_name, ctx)

✔アップデートビュー:nippoUpdateFormView関数

def nippoUpdateFormView(request, pk):
    template_name = "nippo/nippo-form.html"
    obj = get_object_or_404(NippoModel, pk=pk)
    initial_values = {"title": obj.title, "content":obj.content}
    form = NippoFormClass(request.POST or initial_values)
    ctx = {"form": form}
  ctx["object"] = obj
    if form.is_valid():
        title = form.cleaned_data["title"]
        content = form.cleaned_data["content"]
        obj.title = title
        obj.content = content
        obj.save()
    return render(request, template_name, ctx)

✔アクセスして確かめる

先程のページとは違い、「Page not found」のステータスコード404が表示されているのがわかります

まとめ

ローカル環境ではDjangoの設定「DEBUG=True」となっているため、どんなエラーでもわかりやすいメッセージが出てくるようになっています

ただ、Webに公開するとそうもいきません

ステータスコードを正しく返すということでエラーの原因がはっきりとわかるようになります

404ページを返すために、

  1. get_object_or_404メソッドをインポート
  2. get_object_or_404(クラス名, 引数)

の流れを忘れずに頭へ入れておきましょう!

次回は、いよいよ「CRUD」の「D」、アクセスしたページからデータベースのデータを削除する方法を解説していきます

タイトルとURLをコピーしました