Django中dict(request.POST.lists())返回两个字典问题如何解决
问题根因
- 两次字典输出对应两次不同的请求:
- 第一次是点击Send触发的正常POST请求,request.POST携带正常表单数据,返回302状态码说明视图处理完POST后执行了重定向操作
- 第二次是重定向后的GET请求,GET请求的request.POST默认为空,所以打印
{},此时你直接取ids['selected']会触发KeyError,导致500报错
- 现有代码没有对请求方法做判断,不管POST还是GET请求都会执行取selected字段的逻辑,GET请求自然会报错
- HTML代码中
csrf_token放在for循环内,会重复生成多个csrf token字段,不符合规范
解决方案
第一步:修改视图代码,增加请求方法判断,优化多值获取逻辑
直接用Django内置的request.POST.getlist()方法获取同name的多个值,不需要手动转字典:
@login_required(login_url="/users/login") def tresults(request): # 仅处理POST请求 if request.method == "POST": selected_list = request.POST.getlist('selected') print(selected_list) # 可直接拿到所有selected字段的value列表 if selected_list: # 先判断非空再操作,避免空列表报错 msg = selected_list.pop(0) # 剩余业务逻辑写在这里 # 若不需要重定向直接返回对应响应即可,若需要重定向确认目标路由不会再触发tresults的POST逻辑 return redirect("你的目标路由名") # GET请求走这里,对应渲染表单页面的逻辑 return render(request, "你的表单页面文件名.html", context={你需要传给模板的参数})
第二步:优化HTML代码,修正csrf_token位置
把csrf_token放到form标签内部、for循环外面即可,整个表单只需要一个csrf token:
<form id = "{{ msg }}" action="tresults" method="POST"> {% csrf_token %} <!-- 移到此处即可 --> <input type="hidden" name="selected" value="{{ msg }}"> <div class="table-responsive"> <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0"> <thead> <tr> <th>GuildName</th> <th>GuildID</th> <th>Check</th> </tr> </thead> <tbody> {% for guild in guilds %} <tr> <td>{{ guild.name }}</td> <td>{{ guild.id }}</td> <td> <input type="checkbox" name="selected" value="{{ guild.id }}"/> </td> </tr> {% endfor %} </tbody> </table> </div> </form> <a class="dropdown-item" href="#" onclick="document.forms['{{ msg }}'].submit();">Send</a>
内容的提问来源于stack exchange,提问作者Lunar
相关产品推荐
相关产品推荐

