You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:57:53