render_to_response() got an unexpected keyword argument 'context_instance'

来到这个页面的朋友可能大多是使用RequestContext(request)来生成csrf_token 以指望摆脱Forbidden(403)的吧?恭喜你,来对了地方。

在花了一天时间利用远古教学视频学习Django的时候遇到的问题。

其根本原因非常的……简单:Django更新了

简单的试了几下不行之后,就去看了官方文档,记录一下,现在是版本1.11.6,是2017年,21世纪。

文档地址:http://djx.readthedocs.io/en/stable/ref/templates/api.html?highlight=RequestContext#django.template.RequestContext


也不要花时间去看了,我把有用的搬运过来造福社会:

首先,是这个render_to_response方法:

render_to_response()

render_to_response(template_name, context=None, content_type=None, status=None, using=None)[source]

This function preceded the introduction of render() and workssimilarly except that it doesn’t make the request available in theresponse. It’s not recommended and is likely to be deprecated in the future.

看到了吧,根本没有这个参数,而且最后一句说的很明白,这个垃圾函数人家不想伺候了。嗯推荐大家用render。不过也不要灰心,render和这个函数基本上是完全一样的,只是参数顺序不同而已。


接下来是这个context_instance,这个参数,取消了,旧版文档还有。但是,我们有什么理由去学习旧版?

废话不多说,还有代码要写,直接上问题原因和解决方案。见关于RequestContext的文档内容如下:

RequestContext


………blarblar………

In addition to these, RequestContext always enables'django.template.context_processors.csrf'. This is a security relatedcontext processor required by the admin and other contrib apps, and, in caseof accidental misconfiguration, it is deliberately hardcoded in and cannot beturned off in the context_processors option.

………blarblar………

综上,这个什么什么.csrf 看上去为我们封装了一个csrf对象(哪门子对象,就一字符串),事实证明我们看得很准。


所以说,我们之前用的context_instance参数被取消了,想要实现csrf,也就是伪造跨站请求(听上去很专业的术语)就必须在render_to_response()或者render()里设法加入用RequestContext(request)为我们生成的csrf字符串,前面那个长的,在此,仅代表全体Django开发人员建议你不要用了,哈哈。所以就用render()来实现。

所以怎么实现?


render(request,模板名,context,……)


context一看就是我们要的那个参数,但是如果你用了


context=RequestContext(request)


的话,你还真就有点可爱和懵逼了,因为又要报错:


context must be a dict rather than RequestContext

是吧?


什么原因?错误已经写的新清楚了啊,这玩意是个什么RC类型的东西,不是一个字典,解决方案如下:


别用那个了。


官方推出了django.template.context_processors.csrf,来专门处理这种情况,这么专注而专业的方法为何不用?

所以正确之写法:


import 上面那句红的
return render_to_response('XX.html',context=csrf(request))
#或者
return render(request,'xx.html',context=csrf(request))


至此,问题解决。

给耐心看完的朋友一点福利:如果还想传参怎么办!?(因为context已经被占用了)。很简单:


            c=csrf(request)
            c.update({'msg':'nooooooooo'})
            return render_to_response('xxx.html',context=c)#或者render版本的

这样,你的模板里就可以收到 msg了。


猜你喜欢

转载自blog.csdn.net/PlusChang/article/details/78306667