Django视图main.views.home未返回HttpResponse及name未定义报错排查
问题描述
初始报错
The view main.views.home didn't return an HttpResponse object. It returned None instead
排查过程
- 查阅Slack平台多则同类ValueError讨论帖,多数同类问题诱因是视图未返回render响应,但自查代码已经编写了render返回逻辑
- 判断问题与代码中if判断语句有关,但无法定位具体错误点,不清楚如何调整代码才能正常校验浏览器发送的表单请求
- 按评论建议临时移除is_valid校验逻辑,尝试触发新报错排查问题,此时出现名称错误:
name 'name' is not defined,确认代码无法将用户在表单中输入的内容传递到API请求中
问题相关代码
views.py
from http.client import responses from django.shortcuts import render from .forms import SearchUser from .search import search def home(request): if request.method == "POST": form = SearchUser(request.POST) form.cleaned_data["name"] else: return render(request, "main/home.html", { 'form': SearchUser(), # Reference to form 'userid': search(request), # 'mmr':NA, })
search.py
import requests def search(request): data = requests.get( f"https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/{name}/NA1?api_key=RGAPI-d1224a2c-9130-45ff-8c05-0656d56d105f") return data.json()['puuid']
urls.py
from django.urls import path from . import views urlpatterns = [ path("", views.home, name=""), #path("", views.search, name=""), ]
home.html
{% extends 'main/base.html'%} {% block content %} <h2>Valorant Ranked Checker</h2> <form method="post" action=""> {% csrf_token %} {{form}} <button type="submit" name="search"> Get rank </button> </form> <p><strong>{{userid}} - {{mmr}}</strong></p> {% endblock %}
forms.py
from django import forms class SearchUser(forms.Form): name = forms.CharField(label="Name", max_length=200)
问题根因
代码存在3个核心错误:
- 视图响应缺失:
home视图仅对非POST请求分支做了return render处理,用户提交表单走POST分支时,代码没有任何返回值,Django收到None就会抛出未返回HttpResponse的错误 - 表单取值逻辑错误:访问
form.cleaned_data前必须先调用form.is_valid()做合法性校验,否则清洗后的数据不会生成,无法拿到用户输入的值 - 参数传递逻辑错误:
- 从表单取到的name值没有传递给
search函数,search函数内部直接使用未定义的name变量,触发名称错误 - GET请求是首次打开页面的场景,此时用户还没有输入查询ID,直接调用
search函数请求API必然出错
- 从表单取到的name值没有传递给
修复方案
- 调整视图逻辑,不管是GET还是POST请求,最终统一返回render响应,避免出现无返回值的分支
- 表单取值前先做合法性校验,校验通过后再取cleaned_data里的值
- 修改search函数的参数定义,显式接收要查询的name值,不要在函数内部使用未定义的变量
- 仅在表单校验通过后再调用API查询,GET请求阶段不触发接口调用
修复后的代码参考:
修复后的views.py
from django.shortcuts import render from .forms import SearchUser from .search import search def home(request): form = SearchUser() userid = None if request.method == "POST": form = SearchUser(request.POST) if form.is_valid(): search_name = form.cleaned_data["name"] userid = search(search_name) return render(request, "main/home.html", { 'form': form, 'userid': userid, })
修复后的search.py
import requests def search(name): resp = requests.get( f"https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/{name}/NA1?api_key=RGAPI-d1224a2c-9130-45ff-8c05-0656d56d105f") resp.raise_for_status() return resp.json()['puuid']
内容的提问来源于stack exchange,提问作者Blue
相关产品推荐
相关产品推荐

