0

I am building a Django project where users can upload pictures. I am wondering what I should do to not show the original picture name.

I want the url to be something like /pic/randomnumber, and when the picture is downloaded from the website, it would have the name randomnumber.jpg. For example, all the pictures on Tumblr have the name tumblr_blabla.jpg.

I think this is something that should be done in models.py, but I am not quite sure how to implement it.

user2857014
  • 507
  • 3
  • 10
  • 22

2 Answers2

0

IMO you should write method save in your model Something like that:

from PIL import Image
import os


class YOURS_MODEL_NAME(models.Model):
    photo = models.ImageField(upload_to="photos")
    def save(self, miniature=True):
        super(YOURS_MODEL_NAME, self).save()
        if miniature:
             filepath = self.photo.path


             image = Image.open(filepath)           
             new_filepath = filepath.split('.')
             new_filepath = '.'.join("HERE YOU CAN ADD EVERYTHING TO PATH TO THIS PHOTO") + "." + new_filepath[-1].lower()

            try:
                image.save(new_filepath, quality=90, optimize=1)
            except:
                image.save(new_filepath, quality=90)

            photo_name = self.photo.name.split('.')
            photo_name = '.'.join("HERE YOU CAN ADD EVERYTHING YOU WANT TO 'PHOTO NAME'") + "." + photo_name[-1].lower()
            self.photo = photo_name

            self.save(miniature=False)

            # remove old image
            os.remove(filepath)
Marek Szmalc
  • 783
  • 1
  • 7
  • 15
0

The upload_to argument in your Model definition can be a callable function which you use to customize the name of the file. Taken from the Django docs on FileField (of which ImageField is a subclass):

upload_to takes two arguments: instance and filename, (where filename is the original filename, which you may also chose to ignore).

Something similar to this in models.py should do the trick:

def random_filename(instance, filename):

    file_name = "random_string" # use your choice for generating a random string!

    return file_name


class SomeModel(models.Model):
    file = models.ImageField(upload_to=random_filename)

(this is similar to the answer this question about FileFields).

If you are going down this path, I would recommend that you use either the hash/checksum or date/time of the file upload. Something along these lines should work (although I haven't tested it myself!):

from hashlib import sha1

def unique_filename(instance, field):

    filehash = sha1()

    for chunk in getattr(instance, field).chunks():
        filehash.update(chunk)

    return filehash

class SomeModel(models.Model):
    file = models.ImageField(upload_to=unique_filename(field='file'))

Hope this helps!

Community
  • 1
  • 1
Marc Gouw
  • 108
  • 4