当我提交了一个POST请求Content-Type
的application/json
JSON对象被表示为类型的字典,数组作为数组等等。这是伟大的- ,因为它应该我在服务器上的数据被解码成原生的Python。
但是,当我向我的API发出一个MultiPart发布请求时,该请求当然也包含一个文件,服务器上不会解码任何包含JSON /对象的字段,而我剩下的字符串需要我自己解码。我的应用程序的性质意味着我不能总是知道我将要获得哪些字段。
我的问题是-如何提交包含文件的多部分请求,同时又保留DRF在某些字段中解码JSON数据的功能?我试过一起使用所有3个主要的解析器,但这没有用(通过将API视图的parser_classes设置为它们: parser_classes = (MultiPartParser, JSONParser, FormParser)
以下是一些通过Chrome的开发工具发送的示例请求:
标准发布(不是分段的,没有文件): {"first_name":"Test","last_name":"Shmest","email":[{"channel_type":"Email","value":"[email protected]","name":null,"default":false}],"company":{"position":"Manager","id":"735d2b5f-e032-4ca8-93e4-c7773872d0cc","name":"The Compapa"},"access":{"private":true,"users":[10,1]},"description":"Nice guy!!","address":{"city":"San Fanfanfo","zip":"39292","country":"United States of America","state":"CA","map_url":null,"country_code":"US","address":"123 This street"},"phone":[{"default":false,"type":"Phone","id":"70e2b437-6841-4536-9acf-f6a55cc372f6","value":"+141512312345","name":null}],"position":"","department":"","supervisor":"","assistant":"","referred_by":"","status":"","source":"","category":"Lead","do_not_call":false,"do_not_text":false,"do_not_email":false,"birthday":null,"identifier":""}
DRF可以很好地读取此有效负载,并且所有值都设置为它们的本机等效项。
与文件和字段之一组成的多部分是JSON编码的对象:
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="file"; filename="image.png"
Content-Type: image/png
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="first_name"
Test
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="last_name"
Shmest
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="email"
[{"channel_type":"Email","value":"[email protected]","name":null,"default":false}]
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="company"
{"position":"Manager","id":"735d2b5f-e032-4ca8-93e4-c7773872d0cc","name":"The Compapa"}
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="access"
{"private":true,"users":[10,1]}
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="description"
Nice guy!!
------WebKitFormBoundaryPfKUrmBd9vRwp5Rb
Content-Disposition: form-data; name="address"
我正在寻找的是看是否有某种方法可以像常规POST中那样在多部分请求中自动进行JSON解码,然后再深入研究手动解码所有字段以检查它们是否为JSON。在提出请求之前,我将要获得的大多数字段都是未知的,因为每个用户可能具有不同的字段组合。
我创建了一个新的Parser对象,以处理带有包含JSON的字段的MultiPart文件上载的情况。如果有人需要,代码在下面。
import json
from rest_framework.parsers import BaseParser, DataAndFiles
from django.conf import settings
from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser, MultiPartParserError
from django.utils import six
from rest_framework.exceptions import ParseError
class MultiPartJSONParser(BaseParser):
"""
Parser for multipart form data which might contain JSON values
in some fields as well as file data.
This is a variation of MultiPartJSONParser, which goes through submitted fields
and attempts to decode them as JSON where a value exists. It is not to be used as a replacement
for MultiPartParser, only in cases where MultiPart AND JSON data are expected.
"""
media_type = 'multipart/form-data'
def parse(self, stream, media_type=None, parser_context=None):
"""
Parses the incoming bytestream as a multipart encoded form,
and returns a DataAndFiles object.
`.data` will be a `QueryDict` containing all the form parameters, and JSON decoded where available.
`.files` will be a `QueryDict` containing all the form files.
"""
parser_context = parser_context or {}
request = parser_context['request']
encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
meta = request.META.copy()
meta['CONTENT_TYPE'] = media_type
upload_handlers = request.upload_handlers
try:
parser = DjangoMultiPartParser(meta, stream, upload_handlers, encoding)
data, files = parser.parse()
for key in data:
if data[key]:
try:
data[key] = json.loads(data[key])
except ValueError:
pass
return DataAndFiles(data, files)
except MultiPartParserError as exc:
raise ParseError('Multipart form parse error - %s' % six.text_type(exc))
解析器可以像在其他视图中一样在API视图中使用:
parser_classes = (MultiPartJSONParser, JSONParser , FormParser)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句