Search code examples
pythondjangofile-uploaddjango-ckeditor

How to create uuid4 file names for images uploaded with Django-CKEeditor?


I want to create random uid file names for images uploaded with the django-ckeditor/uploader.

I've created utils.py in the same folder as settings.py:

import uuid

def get_name_uid():
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (uuid.uuid4(), ext)
    return filename

I would like to add this "random" file name to settings.py:

CKEDITOR_FILENAME_GENERATOR = get_name_uid()

How can I do this? I am not sure how to get the filename that is uploaded in the editor. Should I pass the filename from settings.py to utils.py? Or is there a different way to do this?

Their documentation says the following:

``CKEDITOR_UPLOAD_PATH = "uploads/"``

When using default file system storage, images will be uploaded to "uploads" folder in your MEDIA_ROOT and urls will be created against MEDIA_URL (/media/uploads/image.jpg).

If you want be able for have control for filename generation, you have to add into settings yours custom filename generator.

```
# utils.py

def get_filename(filename):
    return filename.upper()
```

```
# settings.py

CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename'
```

CKEditor has been tested with django FileSystemStorage and S3BotoStorage.
There are issues using S3Storage from django-storages.

Solution

  • It's basically all spelled out for you in the docs:

    def get_filename(filename):
        return filename.upper()  # returns the uppercase version of filename
    

    So the example function get_filename gets the uploaded filename passed in and you're supposed to return the filename you want it to be. This is what we call a callback.

    What the callback gets passed in as arguments is called the "callback signature" and the docs specify neatly what it gets.

    So put the function in a place where it makes sense. I would choose mysite/mysite/utils.py given the structure outlined in the tutorial, under the heading "Let’s look at what startproject created:". So in the same directory as settings.py. I would name it generate_uuid4_filename and mysite/mysite/utils.py would look like this:

    import uuid
    import os.path
    
    def generate_uuid4_filename(filename):
        """
        Generates a uuid4 (random) filename, keeping file extension
    
        :param filename: Filename passed in. In the general case, this will 
                         be provided by django-ckeditor's uploader.
        :return: Randomized filename in urn format.
        :rtype: str
        """
        discard, ext = os.path.splitext(filename)
        basename = uuid.uuid4().urn
        return ''.join(basename, ext)
    

    Now update your settings.py:

    # Near the rest of the CKEditor variables
    CKEDITOR_FILENAME_GENERATOR = '<app_label>.utils.generate_uuid4_filename'
    

    And you're done. Good luck!