如何在 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 中更改上传文件的文件名?的主要内容,如果未能解决你的问题,请参考以下文章

Django:下载上传的文件

如何在django中获取上传的文件名

如何在 Django 中上传文件? [关闭]

如何在 Django 中上传文件? [关闭]

如何在 CKeditor 上传中向 POST 值添加字段

django如何取用户上传的头像