I'm working on a Django web app that allows users to upload presentations. The presentation needs to be converted to images, one for each slide, and the images need to be saved to an ImageField as part of a model. However, when I try to save the local image to the model, Django throws a UnicodeDecodeError on the header of the image file.
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte
I did a little reading, and found that this is part of the valid header for a PNG image file. It seems that for whatever reason, Django is attempting to decode the binary file as unicode.
Here's the model I'm attempting to save the image to:
class PresentationSlide(models.Model):
...
image = models.ImageField(upload_to=upload_to)
The upload_to function saves uploaded files with a base64 encoded UUID.
In a view, I validate the form, get the presentation file, and use a custom library to convert it to individual images in a temporary directory. The idea then is to create a PresentationSlide instance for each of these images.
Below is how I attempt to create the model instances and save the images.
presentation = Presentation.objects.create(
description=form.cleaned_data['description'])
slides = [PresentationSlide.objects.create(
presentation=presentation, order=order,
duration=form.cleaned_data['slide_interval'])
for order, image in enumerate(slide_images)]
for image_path, slide in zip(sorted(slide_images), slides):
with open(image_path) as image:
slide.image.save(image.name, File(image))
What's causing Django to attempt to decode this binary file as Unicode text?
Make sure you open the file descriptor in binary mode.
for image_path, slide in zip(sorted(slide_images), slides):
with open(image_path, mode='rb') as image:
slide.image.save(image.name, File(image))
By default open will return a TextIOWrapper that attempts to interpret text.