render_to_response() got an unexpected keyword argument 'context_instance'

来源:互联网 发布:白金数据txt 编辑:程序博客网 时间:2024/06/03 08:35

来到这个页面的朋友可能大多是使用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 ofrender() and workssimilarly except that it doesn’t make therequest 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了。


阅读全文
0 0