3

クエリセットに何かがない場合にユーザーをリダイレクトするexcept句を記述したいと思います。どんな提案も歓迎します。私はPythonの初心者ですが、ここで問題になります。

これが私の現在のコードです:

def get_queryset(self):
    try:
        var = Model.objects.filter(user=self.request.user, done=False)
    except:
        pass

    return var

私はこのようなことをしたい:

def get_queryset(self):
    try:
        var = Model.objects.filter(user=self.request.user, done=False)
    except:
        redirect('add_view')

    return var
4

2 に答える 2

6

メソッド内の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 = Falsegetこのように見えるようにするには、メソッドをオーバーライドする必要があると思います(テストされていません)。

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)
于 2012-06-13T17:10:10.507 に答える
3

これは、@Alasdairの回答を完全に補足するものです。それは本当にコメントであるはずですが、そのように適切にフォーマットすることができませんでした。を実際に再定義getする代わりにListView、次のように単純にオーバーライドできます。

class MyView(ListView):
    allow_empty = False # Causes 404 to be raised if queryset is empty

    def get(self, request, *args, **kwargs):
        try:
            return super(MyView, self).get(request, *args, **kwargs)
        except Http404:
            return HttpResponseRedirect("/empty-queryset-url/")

そうすれば、あなたはの実装全体に対して責任を負いませんget。Djangoが将来それを変更した場合でも、問題はありません。

于 2012-06-13T17:37:29.447 に答える