[Django]-Django. How to save a ContentFile edited with Pillow

4👍

Background

Though InMemoryUploadedFile is primarily intended to be used by MemoryFileUploadHandler, it can be used for other purposes as well. It should be noted that MemoryFileUploadHandler is for handling the situation when a user uploads a file to your server using a webform or a widget. However what you are handling is a situation the user merely provides a link and you download a file on to your web server.

Let us also recall that ImageFile is essentially a reference to a file stored on your filesystem. Only the name of the file is entered in the database and the file’s content itself is stored in the storage system. Django allows you to specify different storage systems so that the file can be saved on the cloud if you need to.

Solution

All you need to do is to pass the content of the image that you generate using Pillow with a filename to ImageField. And that content can be sent through a InMemoryUploaded file or a ContentFile. However there isn’t a need to use both.

So this is your model.

class CMagicPy(models.Model):
    image = models.ImageField(upload_to=create_path)

    # over ride of save method not needed here.

This is your view.

  try:
     # form stuff here

     answer = requests.get(url_image)

     image = Image.open(StringIO(answer.content))
     new_image = image.rotate(90) #image.crop((0, 0, 22, 22))
     stringio_obj = StringIO()


     new_image.save(stringio_obj, format="JPEG")
     image_file = InMemoryUploadedFile(stringio_obj, 
         None, 'somefile.jpg', 'image/jpeg',
         stringio_obj.len, None)

     new_card = CMagicPy()
     new_card.image.save('bada.jpg',image_file)
     new_card.save()

 except:
     # note that in your original code you were not catching
     # an exception. This is probably what made it harder for
     # you to figure out what the root cause of the problem was
     import traceback
     traceback.print_exc()
     return HttpResponse('error')
 else:
     return HttpResponse('done')

Footnotes

Exception handling has been added because things can and will go wrong.

Instead of using JPEG and image/jpeg you should use answers.headers[‘Content-type’] and choose the appropriate one.

👤e4c5

2👍

Try this self.image.save(some_file_path, ContentFile(image_stringio)). And it seems to me that you don’t need to override save() in model.

Leave a comment