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

Django表单上传文件报‘bad filename’,设置内存阈值后异常

问题描述

在Django项目中使用PyMuPDF生成PDF预览图的代码原本运行正常,但将DATA_UPLOAD_MAX_MEMORY_SIZE和FILE_UPLOAD_MAX_MEMORY_SIZE设置为500MB后,出现bad filename错误。

  • 未设置阈值时,self.request.FILES['book_file'].file是tempfile._TemporaryFileWrapper对象
  • 设置阈值后,该对象变为_io.BytesIO对象

相关代码:

def form_valid(self, form):
    text_book = form.save(commit=False)
    text_book.owner_id = self.request.user.pk
    # i'm trying to get the first page to make preview image
    my_file = self.request.FILES['book_file'].file
    pdf_file = fitz.open(my_file)
    page = pdf_file.load_page(0)
    pix = page.get_pixmap()
    preview_image = Image.frombytes('RGB', [pix.width, pix.height], pix.samples)
    preview_image.thumbnail((200, 200))
    image_io = BytesIO()
    preview_image.save(image_io, format='JPEG')
    image_data = image_io.getvalue()
    content_file = ContentFile(image_data)
    text_book.preview_image.save(f'text_book_preview_image{Path(text_book.book_file.name).stem}_preview.jpg',
                                    content_file,
                                    save=False)

    text_book.save()
    return HttpResponseRedirect(self.success_url)

设置的配置:

DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 500
FILE_UPLOAD_MAX_MEMORY_SIZE = DATA_UPLOAD_MAX_MEMORY_SIZE
问题原因

Django的文件上传机制会根据FILE_UPLOAD_MAX_MEMORY_SIZE判断文件存储方式:

  • 当文件大小小于阈值时,文件会直接保存在内存中,对应BytesIO对象
  • 当文件大小大于阈值时,会生成临时文件,对应tempfile._TemporaryFileWrapper对象

PyMuPDF的fitz.open()方法默认会通过文件名后缀判断文件类型,但BytesIO对象没有真实的文件名,无法自动识别PDF格式,因此抛出bad filename错误。

解决方案

修改fitz.open()的调用方式,手动指定文件类型为pdf,让PyMuPDF无需通过文件名识别格式:

def form_valid(self, form):
    text_book = form.save(commit=False)
    text_book.owner_id = self.request.user.pk
    # 获取上传的文件对象
    book_file = self.request.FILES['book_file']
    # 手动指定filetype为'pdf',兼容内存中的BytesIO和临时文件
    pdf_file = fitz.open(stream=book_file.read(), filetype='pdf')
    page = pdf_file.load_page(0)
    pix = page.get_pixmap()
    preview_image = Image.frombytes('RGB', [pix.width, pix.height], pix.samples)
    preview_image.thumbnail((200, 200))
    image_io = BytesIO()
    preview_image.save(image_io, format='JPEG')
    image_data = image_io.getvalue()
    content_file = ContentFile(image_data)
    text_book.preview_image.save(f'text_book_preview_image{Path(book_file.name).stem}_preview.jpg',
                                    content_file,
                                    save=False)

    text_book.save()
    return HttpResponseRedirect(self.success_url)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:13:01