我试图使用Python请求模块将一些数据和文件发送到我的django rest应用程序但是得到以下错误.
raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary) MultiPartParserError: Invalid boundary in multipart: None
码:-
import requests payload={'admins':[ {'first_name':'john' ,'last_name':'white' ,'job_title':'CEO' ,'email':'test1@gmail.com' }, {'first_name':'lisa' ,'last_name':'markel' ,'job_title':'CEO' ,'email':'test2@gmail.com' } ], 'company-detail':{'description':'We are a renowned engineering company' ,'size':'1-10' ,'industry':'Engineering' ,'url':'http://try.com' ,'logo':'' ,'addr1':'1280 wick ter' ,'addr2':'1600' ,'city':'rkville' ,'state':'md' ,'zip_cd':'12000' ,'phone_number_1':'408-393-254' ,'phone_number_2':'408-393-221' ,'company_name':'GOOGLE'} } files = {'upload_file':open('./test.py','rb')} import json headers = {'content-type' : 'application/json'} headers = {'content-type' : 'multipart/form-data'} #r = requests.post('http://127.0.0.1:8080/api/create-company-profile/',data=json.dumps(payload),headers=headers,files=files) r = requests.post('http://127.0.0.1:8080/api/create-company-profile/',data=payload,headers=headers,files=files) print r.status_code print r.text
Django代码: -
class CompanyCreateApiView(CreateAPIView): parser_classes = (MultiPartParser, FormParser,) def post(self, request, *args, **kwargs): print 'request ==', request.data
7stud.. 8
好的,我忘记了你的标题.根据规格:
Content-Type = "Content-Type" ":" media-typeMIME提供了许多"多部分"类型 - 单个消息体内的一个或多个实体的封装.所有多部分类型共享一个通用语法,...并且必须包含边界参数作为媒体类型值的一部分.
以下是包含multipart/form-data的请求:
POST /myapp/company/ HTTP/1.1 Host: localhost:8000 Content-Length: 265 Accept-Encoding: gzip, deflate Accept: */* User-Agent: python-requests/2.9.0 Connection: keep-alive Content-Type: multipart/form-data; boundary=63c5979328c44e2c869349443a94200e --63c5979328c44e2c869349443a94200e Content-Disposition: form-data; name="hello" world --63c5979328c44e2c869349443a94200e Content-Disposition: form-data; name="mydata"; filename="data.txt" line 1 line 2 line 3 line 4 --63c5979328c44e2c869349443a94200e--
查看数据部分如何按边界分隔:
--63c5979328c44e2c869349443a94200e--
我们的想法是将某些东西用于不太可能出现在数据中的边界.请注意,边界包含在Content-Type
请求的标头中.
该请求由此代码生成:
import requests myfile = {'mydata': open('data.txt','rb')} r = requests.post(url, #headers = myheaders data = {'hello': 'world'}, files = myfile )
看起来您正在仔细关注django-rest-framework 文档中的以下注释:
注意:在开发客户端应用程序时,请始终记住确保在HTTP请求中发送数据时设置Content-Type标头.
如果您没有设置内容类型,大多数客户端将默认使用'application/x-www-form-urlencoded',这可能不是您想要的.
但是当你使用时requests
,如果你Content-Type
自己指定标题,那么requests
假设你知道你正在做什么,并且它不会Content-Type
用Content-Type
它本来提供的标题覆盖你的标题.
您没有在Content-Type
标题中提供边界- 根据需要.你怎么能?您没有组装请求的主体并创建边界来分隔各种数据,因此您无法知道边界是什么.
当django-rest-framework
笔记说您应该Content-Type
在请求中包含标题时,这意味着:
您或用于创建请求的任何程序都需要包含
Content-Type
标题.
所以@AChampion在评论中是完全正确的:在所有文档广告之后requests
提供:Content-Type header
requests
请求从Python HTTP/1.1中获取所有工作
requests
是这样的:如果你提供一个files
关键字arg,那么请求使用Content-Type
标题,multipart/form-data
并在标题中指定一个边界; 然后requests
使用边界组装请求的主体.如果你提供了一个data
关键字参数,然后请求使用Content-Type
的application/x-www-form-urlencoded
,这只不过是组装的所有键和值的字典成这种格式:
x=10&y=20
无需边界.
而且,如果你同时提供files
关键字ARG和data
关键字ARG,然后请求使用Content-Type
的multipart/form-data
.
好的,我忘记了你的标题.根据规格:
Content-Type = "Content-Type" ":" media-typeMIME提供了许多"多部分"类型 - 单个消息体内的一个或多个实体的封装.所有多部分类型共享一个通用语法,...并且必须包含边界参数作为媒体类型值的一部分.
以下是包含multipart/form-data的请求:
POST /myapp/company/ HTTP/1.1 Host: localhost:8000 Content-Length: 265 Accept-Encoding: gzip, deflate Accept: */* User-Agent: python-requests/2.9.0 Connection: keep-alive Content-Type: multipart/form-data; boundary=63c5979328c44e2c869349443a94200e --63c5979328c44e2c869349443a94200e Content-Disposition: form-data; name="hello" world --63c5979328c44e2c869349443a94200e Content-Disposition: form-data; name="mydata"; filename="data.txt" line 1 line 2 line 3 line 4 --63c5979328c44e2c869349443a94200e--
查看数据部分如何按边界分隔:
--63c5979328c44e2c869349443a94200e--
我们的想法是将某些东西用于不太可能出现在数据中的边界.请注意,边界包含在Content-Type
请求的标头中.
该请求由此代码生成:
import requests myfile = {'mydata': open('data.txt','rb')} r = requests.post(url, #headers = myheaders data = {'hello': 'world'}, files = myfile )
看起来您正在仔细关注django-rest-framework 文档中的以下注释:
注意:在开发客户端应用程序时,请始终记住确保在HTTP请求中发送数据时设置Content-Type标头.
如果您没有设置内容类型,大多数客户端将默认使用'application/x-www-form-urlencoded',这可能不是您想要的.
但是当你使用时requests
,如果你Content-Type
自己指定标题,那么requests
假设你知道你正在做什么,并且它不会Content-Type
用Content-Type
它本来提供的标题覆盖你的标题.
您没有在Content-Type
标题中提供边界- 根据需要.你怎么能?您没有组装请求的主体并创建边界来分隔各种数据,因此您无法知道边界是什么.
当django-rest-framework
笔记说您应该Content-Type
在请求中包含标题时,这意味着:
您或用于创建请求的任何程序都需要包含
Content-Type
标题.
所以@AChampion在评论中是完全正确的:在所有文档广告之后requests
提供:Content-Type header
requests
请求从Python HTTP/1.1中获取所有工作
requests
是这样的:如果你提供一个files
关键字arg,那么请求使用Content-Type
标题,multipart/form-data
并在标题中指定一个边界; 然后requests
使用边界组装请求的主体.如果你提供了一个data
关键字参数,然后请求使用Content-Type
的application/x-www-form-urlencoded
,这只不过是组装的所有键和值的字典成这种格式:
x=10&y=20
无需边界.
而且,如果你同时提供files
关键字ARG和data
关键字ARG,然后请求使用Content-Type
的multipart/form-data
.