Django中request.POST为空的原因及源码解析

阿麦
阿麦
发布时间:2026-10-13| 4人浏览过
原创

本文分析了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获取不到内容问题的全部内容,希望能对大家有所帮助。欢迎大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。