在django中,修改上传文件的文件名

时间:2021-12-03 16:25:09

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"))

相关文章