1

I want to upload a file with filename as email of the uploader. I know this is not a OS file system issue, nor a unsupported python operation because I did save images with this format in python. Now I want to save the images in model(Specifically ImageField).

I'm using OverwriteStorage to overwrite images if there is some existing image with same name.

Saving the image

model = Model.objects.create(email=email)
# Blob to image
tempfile_io = io.BytesIO()
img.save(tempfile_io, 'JPEG')
image_file = InMemoryUploadedFile(tempfile_io, None, email + ".jpeg",'image/jpeg',tempfile_io.getbuffer().nbytes, None)
print("email is", email)
model.pic.save(email + ".jpg",image_file)

Model

class Model(models.Model):
    email = models.EmailField()
    pic = models.ImageField(upload_to="pics", storage=OverwriteStorage())

OverwriteStorage

class OverwriteStorage(FileSystemStorage):
    def get_available_name(self, name, *args, **kwargs):
        print("name is", name)
        if self.exists(name):
            self.delete(name)
        return name

But for some reason, I don't get the exact name in OverwriteStorage-get_available_name.

email is xyz@example.com
name is xyzexamle.com.jpg

Notice how the @ sign is brutally removed. Is there any file name string check i need to disable. How can I make Django use the exact file name given(whenever possible)?

1 Answers1

3

You will have to override get_valid_name(name) as documented

get_valid_name(name)

Returns a filename suitable for use with the underlying storage system. The name argument passed to this method is either the original filename sent to the server or, if upload_to is a callable, the filename returned by that method after any path information is removed. Override this to customize how non-standard characters are converted to safe filenames.

From source

def get_valid_name(self, name):
    """
    Return a filename, based on the provided filename, that's suitable for
    use in the target storage system.
    """
    return get_valid_filename(name)
anthony2261
  • 140
  • 1
  • 8
iklinac
  • 14,944
  • 4
  • 28
  • 30