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

方法中的 try except 块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行为与您想要的完全不同,因为它从不重定向。它默认显示一个空白页面,如果您设置了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)
于 2012-06-13T17:10:10.507 回答
3

这纯粹是对@Alasdair 答案的补充。它确实应该是一个评论,但不能以这种方式正确格式化。而不是实际重新定义getListView您可以简单地覆盖:

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 回答