如何在 Django 中更改上传文件的文件名?
Posted
技术标签:
【中文标题】如何在 Django 中更改上传文件的文件名?【英文标题】:How to change the file name of an uploaded file in Django? 【发布时间】:2011-02-10 10:40:02 【问题描述】:django 可以更改上传文件的文件名吗?我搜索了,但找不到任何答案。
我的要求是每当上传文件时,其文件名应更改为以下格式。
format = userid + transaction_uuid + file_extension
非常感谢...
【问题讨论】:
【参考方案1】:你是如何上传文件的?
我假设使用FileField
。
FileField.upload_to 的文档说 upload_to
字段,
也可以是可调用的,例如 函数,它将被调用 获取上传路径,包括 文件名。这个可调用对象必须能够 接受两个参数,并返回一个 Unix 风格的路径(带正斜杠) 被传递到存储 系统。这两个论点将是 通过的是:
"instance":一个实例
FileField
所在的模型 定义。更具体地说,这是 特定的实例 正在附加当前文件。“文件名”:之前的文件名 最初给文件。这可能 或可能不考虑时 确定最终目的地 路径。
所以看起来您只需要创建一个函数来处理您的名称并返回路径。
def update_filename(instance, filename):
path = "upload/path/"
format = instance.userid + instance.transaction_uuid + instance.file_extension
return os.path.join(path, format)
【讨论】:
除非文件存在;存储屠宰您的创作以获得唯一的名称吗? 对于其他想要回答的人(比如我),请注意路径不能以 / 开头,否则 django 将由于“可疑操作”而出错,因此您使用 @monkut 的示例 @ 987654326@ 应该是path = "upload/path/"
请注意,如果您以def clean_my_audio_file_field(self):
之类的形式创建自定义验证函数,那么此函数的结果将覆盖您在upload_to= parameter
中所做的任何事情跨度>
如果您希望文件名包含下拉菜单中的值怎么办?如何让models.py
获得该值?
@SoftwareEnthusiastic 你能告诉我这个函数 def update_file_name() 这是写在views.py中的吗?【参考方案2】:
您需要有一个 FileField
和一个调用回调的 upload_to
,请参阅 [1]
您的回调应该调用一个包装器方法,该方法将一个实例作为参数之一,将文件名作为另一个参数。 [2]
按照你喜欢的方式更改它并返回新路径 [3]
1。逻辑
FileField(..., upload_to=method_call(params),....)
2。定义方法
def method_call(params):
return u'abc'
3。包装器:
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")
希望这会有所帮助。 谢谢。
【讨论】:
我在项目和 uuid 中遇到错误。所以我创建了自己的函数作为另一个答案【参考方案3】:如果您希望您的函数可重复使用:
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"))
【讨论】:
【参考方案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
#你只需要这样使用它:#
photo = models.FileField("Attachment", upload_to=generate_unique_name("pics"),max_length=500,help_text="Browse a photo")
【讨论】:
【参考方案5】:以防这可能对任何人都有帮助。
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/"
【参考方案6】:
基本方式是
import os
os.rename('a.txt', 'b.html')
对于您的情况,它可能看起来像
os.rename ("a.txt", "iduuid.ext".format(id=userid, uuid=transaction_uuid, ext=file_extension))
【讨论】:
【参考方案7】:不需要那么多代码,你可以使用单行代码 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值来覆盖文件名。
【讨论】:
请将代码部分作为代码格式而不是文本格式插入以上是关于如何在 Django 中更改上传文件的文件名?的主要内容,如果未能解决你的问题,请参考以下文章