It generates dynamically a directory path and a secure file name for Django FileField.
Main options:
- Ready to use generators.
- Generate secure file name without especial characters.
- Generate file name using a uuid value.
- Dynamically generate paths from the model instance.
- Generate paths using Python datetime formats.
Install the django-upload-to in your virtual environment
$ pip install django-upload-to
Import it in your models file and add it as a upload_to
argument in the FileField
# my_app/models.py
from upload_to import UploadTo
from django.db import models
class MyModel(models.Model):
attachment = models.FileField(upload_to=UploadTo("attachments"))
The path and file name generated will be like this:
"attachments/the-file-name-uploaded.pdf"
Consider the scenario below:
import upload_to
from django.db import models
class MyUser(models.Model):
username = models.CharField(...)
avatar = models.FileField(upload_to=<generator>)
instance = MyUser(username='[email protected]')
Replace the <generator>
fragment by the generators as showed below:
>>> generator = upload_to.UploadTo()
>>> generator(instance, "file.pdf")
"file.pdf"
>>> generator = upload_to.UploadTo(prefix=["files", "documents"])
>>> generator(instance, "file.pdf")
"files/documents/file.pdf"
>>> generator = upload_to.UploadTo(prefix=["pictures", "%Y"])
>>> generator(instance, "file.png")
"pictures/2023/file.png"
# 4. replace file name by a uuid value
>>> generator = upload_to.UuidUploadTo()
>>> generator(instance, "file.pdf")
"b189dfdf25e640b2ba5c497472c20962.pdf"
>>> generator = upload_to.AttrUploadTo(attrs=["username"])
>>> generator(instance, "file.pdf")
"useremailcom/file.pdf"
>>> generator = upload_to.ModelUploadTo()
>>> generator(instance, "file.pdf")
"my_app/user/file.pdf"
# my_app/models.py
import upload_to
from django.db import models
def my_upload_generator(instance, filename):
filename = upload_to.uuid_filename(filename)
path = upload_to.options_from_instance(instance)
return upload_to.upload_to(path, filename)
class MyProfile(models.Model):
user = models.OneToOneField(...)
avatar = models.FileField(upload_to=my_upload_generator)