Django在try except语句中不会重定向到404

4 投票
2 回答
4365 浏览
提问于 2025-04-18 02:04

我现在正在学习Django这个库,但遇到了一些问题。我收到了一个叫做“DoesNotExist”的错误(状态码是500),而不是我期待的404页面错误。我尝试把debug设置为False,但得到的还是一个500状态的页面。

class CategoryView(generic.ListView):
    model = Category
    template_name = 'rango/category.html'
    allow_empty = False

    try:
        def get_context_data(self, *args, **kwargs):
            context = super(CategoryView, self).get_context_data(*args, **kwargs)
            category_name = decode_url(self.kwargs['category_name_url'])
            category = Category.objects.get(name = category_name)
            pages = Page.objects.filter(category = category)
            context['category'] = category
            context['pages'] = pages
            return context   
    except Category.DoesNotExist:
        raise Http404

错误追踪信息:

在访问 /rango/category/Perl/ 时出现了DoesNotExist错误。

匹配查询的类别不存在。

错误追踪信息:文件 "/Library/Python/2.7/site-packages/django/core/handlers/base.py" 在 get_response方法中 114. response = wrapped_callback(request, *callback_args, **callback_kwargs) 文件 "/Library/Python/2.7/site-packages/django/views/generic/base.py" 在 view方法中 69. return self.dispatch(request, *args, **kwargs) 文件 "/Library/Python/2.7/site-packages/django/views/generic/base.py" 在 dispatch方法中 87. return handler(request, *args, **kwargs) 文件 "/Library/Python/2.7/site-packages/django/views/generic/list.py" 在 get方法中 152. context = self.get_context_data() 文件 "/Users/justahack/Documents/Python/tango_with_django_project/rango/views.py" 在 get_context_data方法中 47. category = Category.objects.get(name = category_name) 文件 "/Library/Python/2.7/site-packages/django/db/models/manager.py" 在 get方法中 151. return self.get_queryset().get(*args, **kwargs) 文件 "/Library/Python/2.7/site-packages/django/db/models/query.py" 在 get方法中 307. self.model._meta.object_name)

异常类型:在 /rango/category/Perl/ 出现DoesNotExist异常,异常值: 匹配查询的类别不存在。

任何帮助都非常感谢。

2 个回答

1

还有一种更简单的方法,不用使用 try ... except 这种写法:你可以从 django.shortcuts 导入 get_object_or_404,这样你的代码就可以写成这样:

category = get_object_or_404(Category, name=category_name) 

如果对象不存在,这样写会直接返回一个404错误。

8

问题在于,try/except 这个块在方法外面,所以它无法捕捉到方法内部的异常。要解决这个问题,可以把 try/except 放到方法里面:

def get_context_data(self, *args, **kwargs):
    context = super(CategoryView, self).get_context_data(*args, **kwargs)
    category_name = decode_url(self.kwargs['category_name_url'])

    # HERE
    try:
        category = Category.objects.get(name = category_name)
    except Category.DoesNotExist:
        raise Http404

    pages = Page.objects.filter(category = category)
    context['category'] = category
    context['pages'] = pages
    return context

另外,如果对象不存在,还有一种更好的方式来抛出 404 错误,那就是使用 get_object_or_404() 这个快捷方式:

def get_context_data(self, *args, **kwargs):
    context = super(CategoryView, self).get_context_data(*args, **kwargs)
    category_name = decode_url(self.kwargs['category_name_url'])
    category = get_object_or_404(Category, name = category_name)
    pages = Page.objects.filter(category = category)
    context['category'] = category
    context['pages'] = pages
    return context

撰写回答