从对 Django FileField 的响应中添加 zip 文件
Adding zip file from a response to Django FileField
目前我正在调用一个 API 一个发回 zip 文件的 an。使用 requests
时
res = requests.post('http://url/to/api', files={'file_pro': *my_file*})
我能够通过返回的 zip 作为字符串获得成功的响应。
当我检查 res.contents 的内容时,我得到:
PK\x03\x04\x14\x00\x00\x00\x08\x00\x0c\x83HH\xba\xd2\xf1\t\xa1\x00\x00\x00\x04\x01\x00\x00....05\x06\x00\x00\x00\x00\x08\x00\x08\x00\x1e\x02\x00\x00$\x04\x00\x00\x00\x00
它看起来像是将 zip 文件作为字符串返回。我查看了这个问题 here 以尝试将此字符串转换为原始 zip 文件。具体我写了:
my_file = UploadedFile(file=File(zipfile.ZipFile(StringIO.StringIO(res.content)),'r'))
my_file.save()
尝试保存时出现以下错误:
KeyError: 'There is no item named 65536 in the archive'
我的最终目标是将此 zip 文件绑定到 UploadedFile
class UploadedFile(BaseModel):
file = models.FileField(upload_to='/path', max_length=255)
如果我使用 html 表单到达这个 API 我的浏览器会在请求成功后自动下载 zip。知道如何解决这个问题吗?
requests
库允许您将响应作为二进制数据返回 - http://docs.python-requests.org/en/master/user/quickstart/#binary-response-content。
您不需要使用ZipFile
重建zip,传回的数据应该已经是zip文件的字节。
from django.core.files.uploadedfile import SimpleUploadedFile
# res.content is the bytes of your API response
res = request.post('http://url/to/api', files={'file_pro': *myfile*})
my_file = SimpleUploadedFile('temp.zip', res.content)
# verify the zip file
assert zipfile.is_zipfile(my_file)
# finally save the file
uploaded_file = UploadedFile(file=my_file)
uploaded_file.save()
# play around with the zipfile
with zipfile.ZipFile(uploaded_file.file) as my_zip_file:
print(my_zip_file.infolist())
请注意,zipfile.ZipFile
采用文件名或类似文件的对象。在您的问题中,您直接将 string/bytes 传递给它。
同时考虑重命名 UploadedFile
模型,因为 Django 已经在 django.core.files.uploadedfile.UploadedFile
.
中内置了一个模型
目前我正在调用一个 API 一个发回 zip 文件的 an。使用 requests
res = requests.post('http://url/to/api', files={'file_pro': *my_file*})
我能够通过返回的 zip 作为字符串获得成功的响应。 当我检查 res.contents 的内容时,我得到:
PK\x03\x04\x14\x00\x00\x00\x08\x00\x0c\x83HH\xba\xd2\xf1\t\xa1\x00\x00\x00\x04\x01\x00\x00....05\x06\x00\x00\x00\x00\x08\x00\x08\x00\x1e\x02\x00\x00$\x04\x00\x00\x00\x00
它看起来像是将 zip 文件作为字符串返回。我查看了这个问题 here 以尝试将此字符串转换为原始 zip 文件。具体我写了:
my_file = UploadedFile(file=File(zipfile.ZipFile(StringIO.StringIO(res.content)),'r'))
my_file.save()
尝试保存时出现以下错误:
KeyError: 'There is no item named 65536 in the archive'
我的最终目标是将此 zip 文件绑定到 UploadedFile
class UploadedFile(BaseModel):
file = models.FileField(upload_to='/path', max_length=255)
如果我使用 html 表单到达这个 API 我的浏览器会在请求成功后自动下载 zip。知道如何解决这个问题吗?
requests
库允许您将响应作为二进制数据返回 - http://docs.python-requests.org/en/master/user/quickstart/#binary-response-content。
您不需要使用ZipFile
重建zip,传回的数据应该已经是zip文件的字节。
from django.core.files.uploadedfile import SimpleUploadedFile
# res.content is the bytes of your API response
res = request.post('http://url/to/api', files={'file_pro': *myfile*})
my_file = SimpleUploadedFile('temp.zip', res.content)
# verify the zip file
assert zipfile.is_zipfile(my_file)
# finally save the file
uploaded_file = UploadedFile(file=my_file)
uploaded_file.save()
# play around with the zipfile
with zipfile.ZipFile(uploaded_file.file) as my_zip_file:
print(my_zip_file.infolist())
请注意,zipfile.ZipFile
采用文件名或类似文件的对象。在您的问题中,您直接将 string/bytes 传递给它。
同时考虑重命名 UploadedFile
模型,因为 Django 已经在 django.core.files.uploadedfile.UploadedFile
.