Django 2.0中get_context_data重定向报错:context需为dict而非HttpResponseRedirect
兄弟,你这是踩了Django类视图的一个典型小坑啊!咱们先把问题掰明白,再给你解决办法:
为啥会报这个错?
get_context_data这个方法的本职工作就是给模板准备上下文字典,说白了就是给页面传变量用的,Django明确要求它必须返回一个dict类型的数据。结果你在这儿返回了HttpResponseRedirect重定向对象,完全不符合它的预期,不报错才怪呢😅
正确的做法:把重定向逻辑放到该放的地方
重定向属于请求响应流程的环节,得放在类视图里专门处理请求、返回响应的方法中,比如dispatch、get或者form_valid这些。下面给你几种实用的实现方式:
方式1:用dispatch方法(推荐,通吃GET/POST请求)
dispatch是类视图的入口,所有请求都会先经过这儿,适合提前判断要不要重定向:
from django.views.generic.edit import FormView from django.shortcuts import redirect from django.urls import reverse class LearnQuestion(FormView): form_class = SessionForm template_name = 'learn/learn_question.html' def dispatch(self, request, *args, **kwargs): # 把你原本在get_context_data里的重定向判断逻辑移到这儿 # 举个例子:假设满足某个条件就跳转到success页面 course_learn_id = 123 # 换成你的实际业务值 session = "your_session_value" # 换成你的实际业务值 if 这里写你的重定向判断条件: # 用reverse根据命名空间和视图名生成URL,避免硬编码 redirect_url = reverse('learn:success', kwargs={'course_learn_id': course_learn_id, 'session': session}) return redirect(redirect_url) # 不需要重定向的话,就按正常流程走 return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 这儿安心处理上下文数据就行,比如加个额外变量给模板 context['extra_info'] = "给页面的额外内容" return context
方式2:重写get方法(只处理GET请求场景)
如果你的重定向逻辑只针对GET请求,也可以这么写:
class LearnQuestion(FormView): form_class = SessionForm template_name = 'learn/learn_question.html' def get(self, request, *args, **kwargs): # 同样先做重定向判断 course_learn_id = 123 session = "your_session_value" if 你的重定向条件: redirect_url = reverse('learn:success', kwargs={'course_learn_id': course_learn_id, 'session': session}) return redirect(redirect_url) # 没问题就继续执行原有的GET请求流程 return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 正常准备上下文数据 return context
方式3:表单验证后重定向(POST请求场景)
如果是表单提交验证通过后需要重定向,那就改form_valid方法(FormView默认在表单验证通过后会跳转到success_url,咱们可以自定义这个逻辑):
class LearnQuestion(FormView): form_class = SessionForm template_name = 'learn/learn_question.html' def form_valid(self, form): # 先处理表单验证通过后的业务逻辑 session_data = form.cleaned_data.get('session') course_learn_id = self.kwargs.get('course_learn_id') # 假设从URL参数取id # 判断是否要跳转到success页面 if 你的重定向条件: redirect_url = reverse('learn:success', kwargs={'course_learn_id': course_learn_id, 'session': session_data}) return redirect(redirect_url) # 不需要的话就走默认的success_url跳转 return super().form_valid(form)
最后再划个重点
get_context_data就老老实实做上下文准备,别让它干重定向的活儿!- 重定向这种响应类的操作,一定要放在
dispatch、get、form_valid这类处理请求的方法里。 - 用
reverse+命名空间生成URL,比硬写路径靠谱多了,后期改URL也不用到处找。
内容的提问来源于stack exchange,提问作者Anuj TBE
相关产品推荐
相关产品推荐

