在Django中,是否可以更改上传文件的文件名?我搜索了一下,但是没有找到任何答案。
我的要求是每当有文件上传时,文件名都应按以下格式更改。
format = userid + transaction_uuid + file_extension
非常感谢你...
在Django中,是否可以更改上传文件的文件名?我搜索了一下,但是没有找到任何答案。
我的要求是每当有文件上传时,文件名都应按以下格式更改。
format = userid + transaction_uuid + file_extension
非常感谢你...
FileField
。
FileField.upload_to 的文档显示,upload_to
字段可以是一个可调用对象,比如函数,它将被调用以获取上传路径(包括文件名)。这个可调用对象必须能够接受两个参数,并返回一个 Unix 风格的路径(使用正斜杠)以传递给存储系统。将传入的两个参数分别是:
"instance":定义 FileField
的模型实例。更具体地说,这是当前正在附加当前文件的特定实例。
"filename":最初给定的文件名。在确定最终目标路径时可能会考虑此名称,也可能不会考虑。def update_filename(instance, filename):
path = "upload/path/"
format = instance.userid + instance.transaction_uuid + instance.file_extension
return os.path.join(path, format)
你需要一个带有 upload_to
属性的 FileField
,这个属性调用一个回调函数,参见 [1]。
你的回调函数应该调用一个包装方法,这个方法将实例作为其中一个参数,文件名作为另一个参数。[2]
按照你喜欢的方式进行更改并返回新路径。[3]
FileField(..., upload_to=method_call(params),....)
def method_call(params):
return u'abc'
def wrapper(instance, filename):
return method
这是获取实例所需的rapper方法。
def wrapper(instance, filename):
... Your logic
...
return wrapper
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
sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500,
help_text="Browse a file")
希望这可以帮到你。 谢谢。
如果您希望使您的函数可重用:
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)
你只需要按照这种方式使用它:
document = models.FileField(upload_to=upload_to("my/path"))
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)
path="uploads/"
,用于单个目录。 - Haykinsimport 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
您只需要按照以下方式使用它:
photo = models.FileField("Attachment", upload_to=generate_unique_name("pics"),max_length=500,help_text="Browse a photo")
不需要那么多代码,你只需使用单行代码 fille._name=userid + transaction_uuid + file_extension
就像这样
class xyz(models.Model):
file = models.FileField(upload_to="notice/")
def add(request):
file = request.POST['file']
file._name = request.user.id + transaction_uuid +"."+ file._name.split('.')[1]
你可以通过覆盖文件对象的 _name 值来覆盖文件名。
你也可以尝试这个方法,name_of_submission 可以是你想要附加文件的任何列。
import os
def update_filename(instance, filename):
path = "upload/path/"
ext = filename.split('.')[-1]
format = instance.name_of_submission + str(instance.id_application) + "." + ext
print(format)
return os.path.join(path, format)
基本方法是
import os
os.rename('a.txt', 'b.html')
对于您的情况,它可能看起来像这样
os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))
Hi, i check all the answers, but someone are not updated, this is how in 2022 works whith clean code and following the Django Documentation Here, remember that you need to make a MIGRATION to make this work:
def AvatarSave(instance, filename): #this line changes the name of the file to the user name and put the file extension at the end after the point return 'users/avatars/{0}.{1}'.format(instance.id,filename.split('.')[-1]) avatar = models.ImageField(_("avatar"),upload_to=AvatarSave)
def AvatarSave(instance, filename):
file = 'users/avatars/{0}.{1}'.format(instance.id,
filename.split('.')[-1])
fullFile = os.path.join(settings.MEDIA_ROOT, file)
if exists(fullFile):
os.remove(os.path.join(settings.MEDIA_ROOT, fullFile))
return file
- Oliver Sitán
path = "upload/path/"
,而不是path = "/upload/path/"
。如果路径以斜杠开头,Django 会出现“可疑操作”错误。 - Seb Ashtondef clean_my_audio_file_field(self):
,那么此函数的结果将覆盖您在upload_to=参数
中执行的任何操作。 - Olivier Ponsmodels.py
中可用? - Renel Chesak