Django polls应用提交新增问题表单时addQuestion视图返回None报错
报错根因分析
- 表单提交参数缺失:HTML中所有
<input>标签仅设置了id属性,未设置name属性。浏览器提交表单时会以name作为参数键传递到后端,缺失name会导致request.POST中取不到对应字段,直接触发KeyError。 - 视图异常处理逻辑漏洞:代码中使用裸
except:捕获所有异常后直接执行pass,未返回任何HttpResponse对象,Django检测到视图无返回值就会抛出你遇到的这个报错。 - 隐藏逻辑缺陷:如果问题字段为空,不会创建Question实例
q,后续操作q.choice_set会触发NameError,同样会被异常捕获吞掉,最终导致视图无返回。
修复方案
第一步:修改HTML表单代码
补充所有input的name属性,同时修正label的for属性与input的id对应,可选添加required属性做前端必填校验,避免空提交:
<form action="{% url 'polls:add' %}" method="post"> {% csrf_token %} <label for="question">Question: </label> <input id="question" name="question" type="text" required> <br> <label for="choice1">Choice 1</label> <input id="choice1" name="choice1" type="text" required><br> <label for="choice2">Choice 2</label> <input id="choice2" name="choice2" type="text" required> <br> <label for="choice3">Choice 3</label> <input id="choice3" name="choice3" type="text" required> <br> <input type="submit" value="add"> </form>
第二步:修改addQuestion视图代码
规范请求判断逻辑,补全异常分支的返回值,避免裸except吞错:
from django.shortcuts import render, redirect from django.urls import reverse from .models import Question from django.utils import timezone def addQuestion(request): if request.method == 'POST': q_text = request.POST.get('question', '').strip() choice1 = request.POST.get('choice1', '').strip() choice2 = request.POST.get('choice2', '').strip() choice3 = request.POST.get('choice3', '').strip() # 前端校验失效时后端二次校验必填项 if not all([q_text, choice1, choice2, choice3]): return render(request, 'polls/addQuestion.html', {'error': '所有字段均为必填项'}) try: q = Question(question_text=q_text, pub_date=timezone.now()) q.save() q.choice_set.create(choice_text=choice1, votes=0) q.choice_set.create(choice_text=choice2, votes=0) q.choice_set.create(choice_text=choice3, votes=0) return redirect(reverse('polls:index')) except Exception as e: # 可根据需求打印错误日志排查问题 return render(request, 'polls/addQuestion.html', {'error': '数据保存失败,请重试'}) return render(request, 'polls/addQuestion.html')
内容的提问来源于stack exchange,提问作者Virat
相关产品推荐
相关产品推荐

