Django中request.POST为空的原因及源码解析
本文分析了Django框架中request.POST属性在接收POST请求时返回空QueryDict的现象。通过查看HttpRequest类的源码,发现只有当Content-Type为application/x-www-form-urlencoded时,POST数据才会被解析。若使用application/json等其他类型,request.POST将为空,需通过request.body手动解析。
我通过以下代码发送了一个POST请求:
import urllib3
pool = urllib3.connection_from_url('http://127.0.0.1:8090')
resp = pool.request('POST', '/polls/', fields={'key1':'value1', 'key2':'value2'}, headers={'Content-Type':'application/json'}, encode_multipart=False)
在服务器端,我期望通过request.POST获取到类似<QueryDict: {u'key2': [u'value2'], u'key1': [u'value1']}>的数据,但实际获取到的却是空的<QueryDict: {}>。不过,通过request.body可以获取到原始的请求内容key2=value2&key1=value1。
面对这种情况,我查阅了Django官方文档,但未找到相关解释。因此,我决定通过阅读源码来寻找答案。以下是HttpRequest类中用于获取POST QueryDict的部分函数代码:
def _load_post_and_files(self):
"""Populate self._post and self._files if the content-type is a form type"""
if self.method != 'POST':
self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict()
return
if self._read_started and not hasattr(self, '_body'):
self._mark_post_parse_error()
return
if self.content_type == 'multipart/form-data':
if hasattr(self, '_body'):
# Use already read data
data = BytesIO(self._body)
else:
data = self
try:
self._post, self._files = self.parse_file_upload(self.META, data)
except MultiPartParserError:
# An error occurred while parsing POST data. Since when
# formatting the error the request handler might access
# self.POST, set self._post and self._file to prevent
# attempts to parse POST data again.
# Mark that an error occurred. This allows self.__repr__ to
# be explicit about it instead of simply representing an
# empty POST
self._mark_post_parse_error()
raise
elif self.content_type == 'application/x-www-form-urlencoded':
self._post, self._files = QueryDict(self.body, encoding=self._encoding), MultiValueDict()
else:
self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict()
虽然该函数代码较长,但关键逻辑在于最后的if-elif-else分支。从elif self.content_type == 'application/x-www-form-urlencoded':这一分支可以看出,只有当请求头中的Content-Type为'application/x-www-form-urlencoded'时,request.POST才会被填充。在其他情况下,request.POST将保持为空<QueryDict: {}>。
从这个问题可以看出,Django对Content-Type为'application/json'的请求没有进行任何特殊处理,这与我之前的预期有所不同。
以上就是解决Django中request.POST获取不到内容问题的全部内容,希望能对大家有所帮助。欢迎大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













