如果查询集中没有某些内容,我想编写一个重定向用户的except子句。欢迎任何建议。我是一个Python noob,我得到的是这里的问题。
这是我目前的代码:
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
答案 0 :(得分:5)
get_queryset
方法中的try除了块之外并不合适。首先,如果查询集为空,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 documentation for multiple object mixins和source code,并找到合适的方法来覆盖。
在这种情况下,您会发现ListView
行为与您想要的行为完全不同,因为它永远不会重定向。它默认显示空白页面,如果设置allow_empty = False
则显示404页面。我认为你必须覆盖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)
答案 1 :(得分:2)
这完全是对@ 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将来改变它,你仍然可以去。