You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中访问不存在Week实例时Http404异常未触发的问题排查

你的判断完全正确,问题出在异常捕获的范围和类型上

为什么当前代码没触发404?

当用户访问不存在的week_id时,week = Week.objects.get(pk=week_id)这一行会直接抛出Week.DoesNotExist异常,但这行代码不在你的try代码块内,所以后面的except Week.DoesNotExist根本没机会捕获这个异常,导致原始的DoesNotExist错误直接暴露出来,而不是触发你定义的404页面。

你的try-except块只覆盖了获取selected_choice的逻辑,完全没处理获取week时的异常,这就是问题所在。

解决方法

这里有两种常用的修复方案,你可以根据习惯选择:

方案一:调整try块范围,覆盖week的获取逻辑

把获取week的代码也放进try块里,同时补充处理其他可能的异常(比如用户没选择选项就提交的情况):

from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render, redirect
from .models import Week, Choice

def vote(request, week_id):
    try:
        # 把week的获取也放进try块
        week = Week.objects.get(pk=week_id)
        selected_choice = week.choice_set.get(pk=request.POST["choice"])
    except Week.DoesNotExist:
        # 现在能捕获week不存在的情况了
        raise Http404("Poll for said week does not exist")
    except (KeyError, Choice.DoesNotExist):
        # 处理用户没选选项或选项不存在的情况,返回投票页面并提示错误
        return render(request, 'polls/detail.html', {
            'week': week,
            'error_message': "You didn't select a valid choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return redirect("results", week_id)

方案二:使用Django内置的get_object_or_404快捷函数(更推荐)

Django提供了get_object_or_404工具函数,它会在查询不到对象时自动抛出Http404异常,省去手动写try-except的麻烦,代码更简洁:

from django.shortcuts import get_object_or_404, render, redirect
from .models import Week, Choice

def vote(request, week_id):
    # 直接用get_object_or_404,不存在就自动返回404
    week = get_object_or_404(Week, pk=week_id)
    try:
        selected_choice = week.choice_set.get(pk=request.POST["choice"])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
            'week': week,
            'error_message': "You didn't select a valid choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return redirect("results", week_id)

额外提示

原来的代码还有一个潜在问题:当用户没有选择任何选项就提交表单时,request.POST["choice"]会抛出KeyError异常,之前的代码没有处理这种情况,建议像上面的示例一样补充捕获这个异常,提升用户体验。

内容的提问来源于stack exchange,提问作者user7496931

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:22:33