如何在Django中更改上传文件的文件名?

Sof*_*tic 31 python django django-models django-forms django-views

是否可以在django中更改上传文件的文件名?我搜索过,但找不到任何答案.

我的要求是每当上传文件时,其文件名应以下列格式更改.

format = userid + transaction_uuid + file_extension
Run Code Online (Sandbox Code Playgroud)

非常感谢你...

mon*_*kut 49

你是如何上传文件的?我假设与FileField.

FileField.upload_to的文档说该upload_to字段,

也可以是可调用的,例如函数,它将被调用以获得上载路径,包括文件名.这个callable必须能够接受两个参数,并返回一个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)
Run Code Online (Sandbox Code Playgroud)

  • 对于其他人来说答案(像我一样)请注意路径不能以/开头,否则django会因"可疑操作"而导致错误,所以你使用@monkut的例子`path ="/ upload/path/"`应该是`path ="upload/path /"` (4认同)
  • 除非文件存在;存储屠夫是否为您的创作获得了唯一的名称? (2认同)

A.J*_*.J. 7

你需要有一个FileFieldupload_to调用一个回调,见[1]

你的回调应该调用一个包装器方法,它将一个实例作为params和filename之一获取.[2]

按照你喜欢的方式改变它并返回新的路径[3]

1.逻辑

FileField(..., upload_to=method_call(params),....)
Run Code Online (Sandbox Code Playgroud)

2.定义方法

def method_call(params):
    return u'abc'
Run Code Online (Sandbox Code Playgroud)

3.包装:

def wrapper(instance, filename):
    return method
Run Code Online (Sandbox Code Playgroud)

这是获取实例所需的说唱方法.

def wrapper(instance, filename):
... Your logic
...
return wrapper
Run Code Online (Sandbox Code Playgroud)

完整代码

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
Run Code Online (Sandbox Code Playgroud)

致电方法

sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500,
                                help_text="Browse a file")
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.谢谢.


nic*_*las 6

如果您希望函数可重复使用:

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)
Run Code Online (Sandbox Code Playgroud)

您只需要以这种方式使用它:

document = models.FileField(upload_to=upload_to("my/path"))
Run Code Online (Sandbox Code Playgroud)