DjangoでListViewを使う場合、デフォルトではモデルにデータがない時は HTTP200 で、データがない状態で表示されます。
ただ、モデルにデータがない場合に HTTP404 を表示したい時はどうするか、調べたことをメモしておきます。
目次
環境
調査
公式ドキュメントにより、ListViewが継承している MultipleObjectMixin
が持つ allow_empty
を使えば良さそうでした。
- https://docs.djangoproject.com/ja/2.2/ref/class-based-views/generic-display/#listview
- https://docs.djangoproject.com/ja/2.2/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.allow_empty
stackoverflowにも、同じような回答がありました。
Django: get_object_or_404 for ListView - Stack Overflow
そこで、以下のような
- urls.py
- models.py
- todo_list.html
を用意し、 allow_empty
の挙動を試してみます。
urls.py
urlpatterns = [ path('', NotFoundListView.as_view(), name='todo_list'), ]
models.py
from django.db import models class Todo(models.Model): title = models.CharField(max_length=100) content = models.CharField(max_length=255)
todo_list.html
<body> <main class="container"> <table> <thead> <tr> <th>ID</th> <th>タイトル</th> <th>内容</th> </tr> </thead> <tbody> {% for todo in todo_list %} <tr> <td>{{ todo.id }}</td> <td>{{ todo.title }}</td> <td>{{ todo.content }}</td> </tbody> </table> {% endfor %} </main> </body>
allow_empty=Trueの場合
使うListViewはこんな感じです。
from django.views.generic import ListView from listview404.models import Todo class NotFoundListView(ListView): allow_empty = True # デフォルトのまま model = Todo
結果はこちら。HTTP200です。
allow_empty=Falseの場合
allow_empty
のみ変更します。
from django.views.generic import ListView from listview404.models import Todo class NotFoundListView(ListView): allow_empty = False # 変更 model = Todo
HTTP404 が表示されました。
ソースコード
Githubに上げました。 listview404
が今回のアプリです。
https://github.com/thinkAmi-sandbox/Django22_generic_view-sample