能否用Python requests库在同一POST请求中同时发送文件与数据?
问题解决:同一POST请求同时发送文件和数据
当然可行,你遇到的问题是因为同时使用json和files参数时,requests的处理逻辑会导致数据没有被正确封装到multipart/form-data请求中,Django自然接收不到数据。
正确实现方式
方法1:将数据作为form-data字段传入
把原本的嵌套数据转成字符串,和普通字段一起通过data参数传递,配合files参数发送,requests会自动处理为multipart/form-data格式:
import requests import json files = { 'upload_file': open('creds.txt','rb') } # 嵌套结构转成JSON字符串,方便Django端解析 data = { "collection_name": "detete-test-1", "source": json.dumps({ "data": { "data1": "some random string" } }) } url = 'http://localhost:8000/v1/source/test' r = requests.post(url, data=data, files=files)
Django端接收逻辑
在视图里从request.POST获取普通字段,嵌套的JSON字段需要再解析一次:
import json from django.http import HttpResponse def test_view(request): if request.method == 'POST': # 获取普通字符串字段 collection_name = request.POST.get('collection_name') # 解析嵌套的JSON字段 source = json.loads(request.POST.get('source')) # 获取上传的文件 upload_file = request.FILES.get('upload_file') # 后续业务处理 return HttpResponse('Success')
方法2:将数据直接加入files字典
也可以把数据字段放到files字典中,用(None, 值)的格式标记为非文件字段,requests同样会把它们纳入multipart/form-data请求:
import requests import json files = { 'upload_file': open('creds.txt','rb'), 'collection_name': (None, "detete-test-1"), 'source': (None, json.dumps({"data": {"data1": "some random string"}})) } url = 'http://localhost:8000/v1/source/test' r = requests.post(url, files=files)
这种方式下,Django端的接收逻辑和方法1完全一致。
原代码失效原因
当你同时传入json和files参数时,requests会生成multipart/related类型的请求,而Django默认只处理multipart/form-data类型的表单数据,因此无法解析json参数里的内容。必须把所有数据都整合到form-data结构中,才能让Django同时拿到文件和数据。
内容的提问来源于stack exchange,提问作者Adil Khatri
相关产品推荐
相关产品推荐

