You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中接收content-type为application/octet-stream的文件?

处理Django中application/octet-stream类型的文件上传请求

这个问题我之前碰到过,Django默认确实只会解析multipart/form-data类型请求里的文件到request.FILES,对于application/octet-stream这种二进制流请求,直接用表单肯定拿不到文件,得换个方式处理,给你两种可行的方案:

方案一:直接读取二进制流处理

如果不需要复用现有的表单逻辑,可以直接从request.body读取整个二进制内容,手动处理文件保存或业务逻辑:

from django.http import HttpResponse, HttpResponseBadRequest

def upload_view(request):
    if request.method == 'POST' and request.content_type == 'application/octet-stream':
        # 读取请求体的二进制文件内容
        file_content = request.body
        
        # 尝试从请求头获取文件名(如果第三方服务提供的话)
        content_disposition = request.headers.get('Content-Disposition', '')
        if 'filename=' in content_disposition:
            file_name = content_disposition.split('filename=')[-1].strip('"')
        else:
            # 如果没有文件名,自定义一个默认名称
            file_name = 'uploaded_file.bin'
        
        # 保存文件到本地(示例路径,根据你的项目配置调整)
        with open(f'media/{file_name}', 'wb') as f:
            f.write(file_content)
        
        return HttpResponse('文件上传成功')
    return HttpResponseBadRequest('无效的请求类型,请使用application/octet-stream')

方案二:适配现有表单逻辑

如果你想继续用原来的UploadFileForm,可以手动构造UploadedFile对象,把它加入到request.FILES中,让表单能正常解析:

首先导入需要的类:

from django.core.files.uploadedfile import InMemoryUploadedFile
from io import BytesIO
from django.http import HttpResponse, HttpResponseBadRequest

然后修改视图函数:

def upload_view(request):
    if request.method == 'POST':
        form = None
        if request.content_type == 'application/octet-stream':
            # 处理二进制流请求
            file_content = request.body
            # 获取或生成文件名
            content_disposition = request.headers.get('Content-Disposition', '')
            file_name = content_disposition.split('filename=')[-1].strip('"') if 'filename=' in content_disposition else 'uploaded_file.bin'
            
            # 创建内存中的上传文件对象(大文件建议用TemporaryUploadedFile)
            file_obj = InMemoryUploadedFile(
                BytesIO(file_content),
                field_name='file',  # 对应你的表单中的文件字段名
                name=file_name,
                content_type='application/octet-stream',
                size=len(file_content),
                charset=None
            )
            
            # 复制原FILES并添加构造好的文件对象
            modified_files = request.FILES.copy()
            modified_files['file'] = file_obj  # 替换或添加表单字段对应的文件
            
            # 用修改后的FILES初始化表单
            form = UploadFileForm(request.POST, files=modified_files)
        else:
            # 处理正常的multipart/form-data请求
            form = UploadFileForm(request.POST, files=request.FILES)
        
        if form.is_valid():
            file = form.cleaned_data['file']
            # 这里写你的后续业务逻辑,比如保存到模型
            # 示例:MyFileModel.objects.create(file=file)
            return HttpResponse('文件上传成功')
        else:
            return HttpResponseBadRequest(f'表单验证失败:{form.errors}')
    # GET请求返回上传页面(如果需要的话)
    return render(request, 'upload.html')

注意事项

  • 如果上传的文件很大,InMemoryUploadedFile会占用较多内存,建议改用TemporaryUploadedFile,它会将文件写入系统临时文件,更适合大文件场景。
  • 要确保第三方服务发送请求时,如果能携带Content-Disposition头并指定filename,会让文件名处理更准确;如果没有,就只能用默认名称。
  • 记得在视图中做好请求类型的判断,避免影响正常的表单上传流程。

内容的提问来源于stack exchange,提问作者STRK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:47:08