是否可以在django中更改上传文件的文件名?我搜索过,但找不到任何答案。
我的要求是每当上传文件时,其文件名都应按以下格式更改。
format = userid + transaction_uuid + file_extension
非常感谢...
答案 0 :(得分:48)
你是如何上传文件的?
我假设使用FileField
。
FileField.upload_to的文档说明upload_to
字段
也可以是可调用的,例如a 函数,将被调用 获取上传路径,包括 文件名。这个可调用必须能够 接受两个参数,并返回一个 Unix风格的路径(带正斜杠) 被传递到存储器 系统。这两个论点将是 传递的是:
“实例”:一个实例
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)
答案 1 :(得分:6)
您需要FileField
upload_to
来调用回调,请参阅[1]
你的回调应该调用一个包装器方法,它将一个实例作为params和filename之一获取。 [2]
按照您喜欢的方式更改并返回新路径[3]
FileField(..., upload_to=method_call(params),....)
def method_call(params):
return u'abc'
def wrapper(instance, filename):
return method
这是获取实例所需的说唱歌手方法。
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")
希望这会有所帮助。 感谢。
答案 2 :(得分:5)
如果您希望您的功能可重复使用:
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"))
答案 3 :(得分:1)
基本方法是
import os
os.rename('a.txt', 'b.html')
对于您的情况,它可能看起来像
os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))
答案 4 :(得分:1)
如果这可能对任何人都有帮助。
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)
答案 5 :(得分:0)
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
#您只需要这样使用它:#
photo = models.FileField("Attachment", upload_to=generate_unique_name("pics"),max_length=500,help_text="Browse a photo")
答案 6 :(得分:-1)
不需要那么多代码,你可以使用单行代码 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 值来覆盖文件名。