メソッド内のtryexceptブロックget_queryset
は実際には適切ではありません。まず、Model.objects.filter()
クエリセットが空の場合は例外を発生させません。空のクエリセットを返すだけです。次に、このget_queryset
メソッドは、ではなくクエリセットを返すことを目的としているHttpResponse
ため、そのメソッド内でリダイレクトしようとすると、問題が発生します。
関数ベースのビューを作成する方が簡単だと思うかもしれません。最初の試みは次のようになります。
from django.shortcuts import render
def my_view(request):
"""
Display all the objects belonging to the user
that are not done, or redirect if there are not any,
"""
objects = Model.objects.filter(user=self.request.user, done=False)
if not objects:
return HttpResponseRedirect("/empty-queryset-url/")
return render(request, 'myapp/template.html', {"objects": objects})
利点は、関数のフローが非常に単純であるということです。これには、ジェネリッククラスベースのビューほど多くの機能はありませんListView
(たとえば、ページ付けがありません)が、コードを読んでいる人なら誰でも、ビューが何をしているのかは明らかです。
クラスベースのビューを本当に使用したい場合は、複数のオブジェクトミックスインとソースコードのCBVドキュメントを調べて、オーバーライドする適切なメソッドを見つける必要があります。
ListView
この場合、リダイレクトされることはないため、動作が目的とはまったく異なることがわかります。デフォルトでは空のページが表示されます。設定した場合は404ページが表示されますallow_empty = False
。get
このように見えるようにするには、メソッドをオーバーライドする必要があると思います(テストされていません)。
class MyView(ListView):
def get_queryset(self):
return Model.objects.filter(user=self.request.user, done=False)
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
if len(self.object_list == 0):
return HttpResponseRedirect("/empty-queryset-url/")
context = self.get_context_data(object_list=self.object_list)
return self.render_to_response(context)