<p><strong>DRF定义了多个解析器类,用于解析具有不同媒体类型的请求内容。</strong></p>
<p><code>request.data</code>通常是<code>QueryDict</code>或普通字典,这取决于用于解析请求内容的解析器。在</p>
<ul>
<li><strong>JSONParser:</strong></li>
</ul>
<p>它解析JSON请求内容,即带有<code>.media_type</code>的内容为<code>application/json</code>。在</p>
<ul>
<li><strong>FormParser</strong></li>
</ul>
<p>它解析HTML表单内容。在这里,<strong><code>request.data</code>填充了<code>QueryDict</code>的数据。</strong>这些数据的<code>.media_type</code>为<code>application/x-www-form-urlencoded</code>。在</p>
<ul>
<li><strong>MultiPartParser</strong></li>
</ul>
<p>它解析支持文件上传的多部分HTML表单内容。这里,两个<strong><code>request.data</code>都填充了<code>QueryDict</code></strong>。这些有
<code>.media_type</code>作为<code>multipart/form-data</code>。在</p>
<ul>
<li><strong>FileUploadParser</strong></li>
</ul>
<p>它解析原始文件上载内容。<strong><code>request.data</code>属性是一个包含上载文件的单键<code>file</code>的字典</strong>。在</p>
<p><strong>DRF <a href="http://www.django-rest-framework.org/api-guide/parsers/#how-the-parser-is-determined" rel="noreferrer">determines</a>如何解析?</strong></p>
<p>当DRF访问<code>request.data</code>时,它检查传入请求的<code>Content-Type</code>报头,然后确定使用哪个解析器来解析请求内容。在</p>
<p>在发送数据时,您需要设置<code>Content-Type</code>头,否则它将使用多部分或表单解析器解析请求内容,并在<code>request.data</code>中给您一个<code>QueryDict</code>,而不是字典。在</p>
<p>根据DRF文件</p>
^{bq}$
<p>因此,在发送json编码的数据时,还应将<code>Content-Type</code>头设置为<code>application/json</code>,然后它将按预期工作。在</p>
<p><strong>为什么请求数据有时是<code>QueryDict</code>,有时是{<cd23>}?</strong></p>
<p>这样做是因为<strong>不同的编码具有不同的数据结构和属性。</strong></p>
<p>例如,表单数据是一种编码,它支持相同值的多个键,而json不支持这一点。在</p>
<p>同样,对于JSON数据,<code>request.DATA</code>可能根本不是<code>dict</code>,它可以是一个列表或任何其他JSON原语。在</p>
<p>看看这个<a href="https://groups.google.com/forum/#!topic/django-rest-framework/_9cg6trvbAk" rel="noreferrer">Google Groups thread</a>差不多。在</p>
<p>你需要做什么?</strong></p>
<p>您可以在测试中添加<code>format='json'</code>,当<code>POSTing</code>的数据将设置内容类型并正确序列化数据。在</p>
<pre><code>client.post('url', format='json', data=dict(field_a=3))
</code></pre>
<p>还可以使用<code>content-type</code>参数发送JSON编码的内容。在</p>
^{pr2}$