Is it possible to change the file name of an uploaded file in django? I searched, but couldn't find any answer.
是否可以更改django中上传文件的文件名?我找了找,但没有找到任何答案。
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...
非常感谢你…
3 个解决方案
#1
45
How are you uploading the file? I assume with the FileField
.
如何上传文件?我假设是FileField。
The documentation for FileField.upload_to says that the upload_to
field,
FileField的文档。upload_to表示upload_to字段,
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:
也可以是可调用的,如函数,它将被调用以获取上传路径,包括文件名。这个可调用函数必须能够接受两个参数,并返回一个要传递到存储系统的unix样式的路径(带有前斜杠)。将通过的两个论点是:
"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.“instance”:定义FileField的模型实例。更具体地说,这是当前文件被附加的特定实例。
"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)
#2
6
You need to have a FileField
with the upload_to
that calls to a callback, see [1]
您需要有一个带有upload_to的FileField来调用回调,请参见[1]
Your callback should call a wrapper method which gets an instance as one of the params and filename as the other. [2]
您的回调应该调用包装器方法,该方法将实例作为一个params和文件名作为另一个。[2]
Change it the way you like and return the new path [3]
按照您喜欢的方式更改它,并返回新的路径[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.
这是您需要获得实例的rap方法。
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.
希望这个有帮助。谢谢。
#3
2
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"))
#1
45
How are you uploading the file? I assume with the FileField
.
如何上传文件?我假设是FileField。
The documentation for FileField.upload_to says that the upload_to
field,
FileField的文档。upload_to表示upload_to字段,
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:
也可以是可调用的,如函数,它将被调用以获取上传路径,包括文件名。这个可调用函数必须能够接受两个参数,并返回一个要传递到存储系统的unix样式的路径(带有前斜杠)。将通过的两个论点是:
"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.“instance”:定义FileField的模型实例。更具体地说,这是当前文件被附加的特定实例。
"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)
#2
6
You need to have a FileField
with the upload_to
that calls to a callback, see [1]
您需要有一个带有upload_to的FileField来调用回调,请参见[1]
Your callback should call a wrapper method which gets an instance as one of the params and filename as the other. [2]
您的回调应该调用包装器方法,该方法将实例作为一个params和文件名作为另一个。[2]
Change it the way you like and return the new path [3]
按照您喜欢的方式更改它,并返回新的路径[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.
这是您需要获得实例的rap方法。
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.
希望这个有帮助。谢谢。
#3
2
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"))