How to change the file name of an uploaded file in Django?
Solution 1
How are you uploading the file?
I assume with the FileField
.
The documentation for FileField.upload_to says that the upload_to
field,
may also be a callable, such as a function, which will be called to obtain the upload path, including the filename. This callable must be able to accept two arguments, and return a Unix-style path (with forward slashes) to be passed along to the storage system. The two arguments that will be passed are:
"instance": An instance of the model where the
FileField
is defined. More specifically, this is the particular instance where the current file is being attached."filename":The filename that was originally given to the file. This may or may not be taken into account when determining the final destination path.
So it looks like you just need to make a function to do your name handling and return the path.
def update_filename(instance, filename):
path = "upload/path/"
format = instance.userid + instance.transaction_uuid + instance.file_extension
return os.path.join(path, format)
Solution 2
You need to have a FileField
with the upload_to
that calls to a callback, see [1]
Your callback should call a wrapper method which gets an instance as one of the params and filename as the other. [2]
Change it the way you like and return the new path [3]
1. LOGIC
FileField(..., upload_to=method_call(params),....)
2. define method
def method_call(params):
return u'abc'
3. Wrapper:
def wrapper(instance, filename):
return method
this is the rapper method that you need for getting the instance.
def wrapper(instance, filename):
... Your logic
...
return wrapper
Complete Code
def path_and_rename(path, prefix):
def wrapper(instance, filename):
ext = filename.split('.')[-1]
project = "pid_%s" % (instance.project.id,)
# get filename
if instance.pk:
complaint_id = "cid_%s" % (instance.pk,)
filename = '{}.{}.{}.{}'.format(prefix, project, complaint_id, ext)
else:
# set filename as random string
random_id = "rid_%s" % (uuid4().hex,)
filename = '{}.{}.{}.{}'.format(prefix, project, random_id, ext)
# return the whole path to the file
return os.path.join(path, filename)
return wrapper
Call to Method
sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500,
help_text="Browse a file")
Hope this helps. Thanks.
Solution 3
if you want your function re-usable:
import hashlib
import datetime
import os
from functools import partial
def _update_filename(instance, filename, path):
path = path
filename = "..."
return os.path.join(path, filename)
def upload_to(path):
return partial(_update_filename, path=path)
You just have to use it this way:
document = models.FileField(upload_to=upload_to("my/path"))
Solution 4
import random
import os
def generate_unique_name(path):
def wrapper(instance, filename):
extension = "." + filename.split('.')[-1]
filename = str(random.randint(10,99)) + str(random.randint(10,99)) + str(random.randint(10,99)) + str(random.randint(10,99)) + extension
return os.path.join(path, filename)
return wrapper
#You just have to use it this way:#
photo = models.FileField("Attachment", upload_to=generate_unique_name("pics"),max_length=500,help_text="Browse a photo")
Solution 5
Incase this may help anyone.
import os
import uuid
import random
from datetime import datetime
def user_directory_path(instance, filename):
# Get Current Date
todays_date = datetime.now()
path = "uploads/{}/{}/{}/".format(todays_date.year, todays_date.month, todays_date.day)
extension = "." + filename.split('.')[-1]
stringId = str(uuid.uuid4())
randInt = str(random.randint(10, 99))
# Filename reformat
filename_reformat = stringId + randInt + extension
return os.path.join(path, filename_reformat)
class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)
Software Enthusiastic
Updated on May 15, 2021Comments
-
Software Enthusiastic almost 3 years
Is it possible to change the file name of an uploaded file in django? I searched, but couldn't find any answer.
My requirement is whenever a file is uploaded its file name should be changed in the following format.
format = userid + transaction_uuid + file_extension
Thank you very much...
-
John Mee almost 14 yearsexcepting if the file exists; does the storage butcher your creation to get a unique name?
-
Seb Ashton about 12 yearsFor others coming to the answer (like me) please note that the path cannot start with a / otherwise django will through an error due to a "Suspicious Operation" so you use @monkut 's example
path = "/upload/path/"
should bepath = "upload/path/"
-
Olivier Pons over 8 yearsbe careful that if you create your custom validation function in a form like
def clean_my_audio_file_field(self):
then the result of this function will override whatever you do in theupload_to= parameter
-
Renel Chesak over 6 yearsWhat if you want the file name to include the value from a drop down menu? How can you make that value available to
models.py
? -
Cyley Simon about 6 years@SoftwareEnthusiastic Can you let me know this function def update_file_name() where this was written in views.py?
-
Jorge Arévalo over 4 yearsWhat if you need instance.id to generate the filename?
-
user2471801 over 4 yearsinclude it in the returned string,
return f'{instance.id}/{filename}'
-
The EasyLearn Academy over 3 yearsI got error in project and uuid. so i have created my own function given as another answer
-
Haykins about 3 yearsor the path can be
path="uploads/"
for a single directory -
Khaled about 3 yearsPlease Insert the code part as a code format and not as a text format