Django2中使用Mako模板获取CSRF_COOKIE触发KeyError的解决咨询
解决Django2 + Mako模板中CSRF令牌KeyError的问题
我来帮你搞定这个问题,你遇到的KeyError: 'CSRF_COOKIE'本质是因为直接读取request.META['CSRF_COOKIE']并不靠谱——这个键只有在CSRF中间件已经为当前请求生成并设置了Cookie时才存在(比如POST请求场景),而GET请求下可能就没有这个值。Django其实提供了官方的安全方法来获取CSRF令牌,不用自己去碰META字典。
步骤1:确保CSRF中间件已启用
首先检查你的settings.py,确认MIDDLEWARE列表里包含django.middleware.csrf.CsrfViewMiddleware,这是生成CSRF令牌的基础:
MIDDLEWARE = [ # ... 其他中间件 'django.middleware.csrf.CsrfViewMiddleware', # ... 其他中间件 ]
步骤2:修改自定义render_to_response函数
我们用Django官方提供的get_token函数来获取令牌,替换掉直接读取request.META的逻辑:
首先导入需要的函数:
from django.middleware.csrf import get_token
然后修改生成csrf_token的那一行,并优化上下文处理逻辑(可选,但代码更简洁):
#coding:utf-8 from mako.lookup import TemplateLookup from django.template import RequestContext from django.conf import settings from django.http import HttpResponse from django.middleware.csrf import get_token # 新增导入 def render_to_response(request, template, data=None): context_instance = RequestContext(request) path = settings.TEMPLATES[0]['DIRS'][0] lookup = TemplateLookup( directories=[path], output_encoding='utf-8', input_encoding='utf-8' ) mako_template = lookup.get_template(template) # 合并上下文数据,用flatten简化字典转换 result = context_instance.flatten() if data: result.update(data) # 用get_token安全获取CSRF令牌 csrf_token_value = get_token(request) result['csrf_token'] = '<input type="hidden" name="csrfmiddlewaretoken" value="{0}" />'.format(csrf_token_value) return HttpResponse(mako_template.render(**result))
为什么这个方法有效?
get_token(request)会自动处理所有情况:
- 如果当前请求已经存在有效的CSRF Cookie,它会直接返回Cookie的值;
- 如果没有,它会生成新的CSRF令牌,同时给response设置对应的Cookie,确保后续请求能正常使用;
- 完全避免了直接访问
request.META可能触发的KeyError。
这样修改后,你的Mako模板就能正常获取到CSRF令牌,表单提交时也能通过CSRF验证了。
内容的提问来源于stack exchange,提问作者Jackyfmy
相关产品推荐
相关产品推荐

