Django form field uploading error bad filename

Question:

In that code I try to get the first page to make preview image. I use PyMuPDF library

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)

Everything works. But when I put that in settings:

DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 500
FILE_UPLOAD_MAX_MEMORY_SIZE = DATA_UPLOAD_MAX_MEMORY_SIZE

I get "bad filename".
When code works without MAX_MEMORY_SIZE settings, my_file is
<tempfile._TemporaryFileWrapper object at 0x7f6491f1ae20>
But when I put that settings my_file is
<_io.BytesIO object at 0x7f69b6945950>
What is wrong?

Asked By: Anna_Silchenko

||

Answers:

your code is trying to open a file using a BytesIO object instead of a file path, which is likely causing the "bad filename" error. The difference between tempfile._TemporaryFileWrapper and _io.BytesIO is that the former represents a temporary file on disk, while the latter represents a file-like object in memory.

When you set DATA_UPLOAD_MAX_MEMORY_SIZE and FILE_UPLOAD_MAX_MEMORY_SIZE, you are limiting the size of files that can be uploaded to your server in memory rather than on disk. This means that larger files will not be saved to a temporary file on disk but instead will be held in memory as a BytesIO object.

To fix the "bad filename" error, you may need to modify the code that opens the PDF file to accept a BytesIO object instead of a file path. One way to do this is to pass the my_file object directly to the fitz.open method, like this:

pdf_file = fitz.open(stream=my_file.read())

This should allow your code to work even when DATA_UPLOAD_MAX_MEMORY_SIZE and FILE_UPLOAD_MAX_MEMORY_SIZE are set. However, be aware that if you allow large files to be uploaded and held in memory, you may run into performance issues or memory errors on your server.

Answered By: mikeforonda
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.