Django FileField上传PDF至AWS S3时如何设置正确Content-Type?
解决Django FileField上传PDF时Content-Type不正确的问题
问题背景
你定义了包含FileField的Document模型,通过脚本从外部URL或本地上传PDF到该字段时,文件的Content-Type被设为application/octet-stream,而前端需要正确的application/pdf类型;另外通过django-admin上传的文件Content-Type显示为application/json(这大概率是异常情况,建议检查文件本身或admin配置)。以下是针对脚本上传的解决方案:
方法1:用InMemoryUploadedFile替代ContentFile
ContentFile不支持设置Content-Type,换成InMemoryUploadedFile可以直接指定类型,适合处理字节流内容:
import requests from django.core.files.uploadedfile import InMemoryUploadedFile import io # 获取外部PDF文件 response = requests.get('<external-url>') # 把字节内容转成BytesIO流 file_stream = io.BytesIO(response.content) # 创建带指定Content-Type的上传文件对象 uploaded_file = InMemoryUploadedFile( file_stream, field_name=None, name='document.pdf', content_type='application/pdf', size=len(response.content), charset=None ) # 保存到FileField document.file.save('document.pdf', uploaded_file, save=True)
方法2:通过S3存储的ExtraArgs直接设置
如果你用的是django-storages的S3后端,在save时传入ExtraArgs参数,直接给S3对象指定Content-Type:
import requests from django.core.files.base import ContentFile response = requests.get('<external-url>') file_content = ContentFile(response.content, name='document.pdf') # 保存时指定Content-Type document.file.save( 'document.pdf', file_content, save=True, ExtraArgs={'ContentType': 'application/pdf'} )
方法3:本地文件上传时指定类型
从本地读取文件上传时,同样用InMemoryUploadedFile来设置正确的Content-Type:
from django.core.files.uploadedfile import InMemoryUploadedFile import io with open('本地文件路径.pdf', 'rb') as f: file_stream = io.BytesIO(f.read()) uploaded_file = InMemoryUploadedFile( file_stream, field_name=None, name='local_document.pdf', content_type='application/pdf', size=file_stream.getbuffer().nbytes, charset=None ) document.file.save('local_document.pdf', uploaded_file, save=True)
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

