为何不建议在Django中间件中使用request.POST?
关于Django中提前访问
request.POST的疑问解答 第一个问题:只读request.POST为啥会影响视图工作?
其实啊,Django里的request.POST可不是普通的字典,它是个惰性加载的对象——意思是只有当你第一次访问它的时候,Django才会去解析HTTP请求的整个body内容,把表单数据提取出来存在request.POST里。
这里关键的点是:HTTP请求的body是个只能读取一次的数据流。一旦你提前在中间件或者process_view()里访问了request.POST,Django就会把整个请求体读完并解析成POST数据,这就把原始的数据流给“消耗”完了。
后面视图如果要处理文件上传(比如用到request.FILES),就需要重新读取请求体里的上传数据,但这时候数据流已经空了,自然就没办法正常处理了。所以不是系统“检测”到你读了,而是这个读取动作本身就占用了唯一的请求体资源,导致后续视图的操作失效。
第二个问题:CsrfViewMiddleware为啥不一样?
CsrfViewMiddleware确实会提前和请求体打交道,但它的处理方式很特殊:它不会完整解析整个POST数据,只会读取请求体的前一小部分,专门查找CSRF令牌(也就是csrfmiddlewaretoken字段)。
更重要的是,它读完这部分后,会把读取过的数据流“重置”回去——相当于把看过的内容放回请求体里,让后续的视图还能完整读取整个请求内容。简单说就是它只是“快速瞥了一眼”关键信息,并没有把整个请求体消耗掉,所以不会影响后面视图处理POST数据或者文件上传。
内容的提问来源于stack exchange,提问作者Hamid
相关产品推荐
相关产品推荐

