DjangoのListViewで、対象データがない場合は404ページを表示する

DjangoでListViewを使う場合、デフォルトではモデルにデータがない時は HTTP200 で、データがない状態で表示されます。

f:id:thinkAmi:20191029062825p:plain:w400

 
ただ、モデルにデータがない場合に HTTP404 を表示したい時はどうするか、調べたことをメモしておきます。

 

目次

 

環境

 

調査

公式ドキュメントにより、ListViewが継承している 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です。

f:id:thinkAmi:20191029062825p:plain:w400

 

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 が表示されました。

f:id:thinkAmi:20191029062859p:plain:w400

 

ソースコード

Githubに上げました。 listview404 が今回のアプリです。
https://github.com/thinkAmi-sandbox/Django22_generic_view-sample