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?
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.
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?
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.