Django中self.request.POST.get('searched')返回None问题排查
问题产生原因
- 表单未指定提交方法,默认使用GET请求提交数据。
<form>标签未添加method="post"属性,浏览器默认以GET方式提交表单,所有参数都拼接在URL的查询字符串中,request.POST自然取不到对应值,从提供的请求日志也能明确看到是GET请求类型。 - 自定义的
post方法没有返回值。即使后续触发POST请求,post方法内仅对局部变量searched赋值,没有返回该变量,调用self.post()最终拿到的还是None。 - 类视图方法调用逻辑错误。Django通用视图会自动根据请求的HTTP方法调用对应的处理函数,GET请求不会自动触发
post方法,在get_context_data里手动调用post方法属于逻辑错误,完全没有必要。
解决方法
搜索功能更推荐使用GET请求,方便用户分享搜索结果链接,优先选择方案1:
方案1:保留GET提交方式
- 修改表单代码,移除GET请求不需要的csrf_token,明确指定提交方式为get:
<form class="d-flex" action="{% url 'asset_app_search' %}" method="get"> <input class="form-control me-2" type="search" placeholder="Søg" aria-label="Search" name="searched"> <button class="btn btn-outline-secondary" type="submit">Søg</button> </form>
- 调整视图代码,删除无用的自定义
post方法,直接从request.GET取参数:
class SearchView(generic.TemplateView): template_name = "asset_app/search.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 直接从GET请求取搜索参数 searched = self.request.GET.get('searched') context['searched'] = searched context_entry_today = datetime.date.today() context_entry_overdue = datetime.date.today() - datetime.timedelta(days=90) context_entry_inspection_time = datetime.date.today() - datetime.timedelta(days=76) context['assets'] = models.Asset.objects.order_by('name') context['rooms'] = models.Room.objects.order_by('last_inspected', 'location', 'name') context['bundelReservations'] = models.Bundle_reservation.objects.order_by('return_date') context['loan_assets'] = models.Loan_asset.objects.order_by('return_date') context['to_dos'] = to_do_list_app.models.Jobs.objects.all() context['today'] = context_entry_today context['overdue'] = context_entry_overdue context['inspection_time'] = context_entry_inspection_time return context
方案2:改用POST提交方式
如果业务需要必须用POST提交,按以下方式调整:
- 给表单添加
method="post"属性:
<form class="d-flex" action="{% url 'asset_app_search' %}" method="post">{% csrf_token %} <input class="form-control me-2" type="search" placeholder="Søg" aria-label="Search" name="searched"> <button class="btn btn-outline-secondary" type="submit">Søg</button> </form>
- 调整视图代码,完善
post方法逻辑:
class SearchView(generic.TemplateView): template_name = "asset_app/search.html" def post(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) context['searched'] = request.POST.get('searched') return self.render_to_response(context) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # GET请求时搜索参数默认为空 context['searched'] = None context_entry_today = datetime.date.today() context_entry_overdue = datetime.date.today() - datetime.timedelta(days=90) context_entry_inspection_time = datetime.date.today() - datetime.timedelta(days=76) context['assets'] = models.Asset.objects.order_by('name') context['rooms'] = models.Room.objects.order_by('last_inspected', 'location', 'name') context['bundelReservations'] = models.Bundle_reservation.objects.order_by('return_date') context['loan_assets'] = models.Loan_asset.objects.order_by('return_date') context['to_dos'] = to_do_list_app.models.Jobs.objects.all() context['today'] = context_entry_today context['overdue'] = context_entry_overdue context['inspection_time'] = context_entry_inspection_time return context
内容的提问来源于stack exchange,提问作者Reventlow
相关产品推荐
相关产品推荐

