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

时间:2010-04-21 04:49:23

标签: python django django-models django-forms django-views

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

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

format = userid + transaction_uuid + file_extension

非常感谢...

7 个答案:

答案 0 :(得分:48)

你是如何上传文件的? 我假设使用FileField

FileField.upload_to的文档说明upload_to字段

  

也可以是可调用的,例如a   函数,将被调用   获取上传路径,包括   文件名。这个可调用必须能够   接受两个参数,并返回一个   Unix风格的路径(带正斜杠)   被传递到存储器   系统。这两个论点将是   传递的是:

     

实例”:一个实例   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)

答案 1 :(得分:6)

您需要FileField upload_to来调用回调,请参阅[1]

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

按照您喜欢的方式更改并返回新路径[3]

1。 LOGIC

FileField(..., upload_to=method_call(params),....)

2。定义方法

def method_call(params):
    return u'abc'

3。包装

def wrapper(instance, filename):
    return method

这是获取实例所需的说唱歌手方法。

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

希望这会有所帮助。 感谢。

答案 2 :(得分:5)

如果您希望您的功能可重复使用:

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

答案 3 :(得分:1)

基本方法是

import os

os.rename('a.txt', 'b.html')

对于您的情况,它可能看起来像

os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))

答案 4 :(得分:1)

如果这可能对任何人都有帮助。

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)

答案 5 :(得分:0)

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

答案 6 :(得分:-1)

不需要那么多代码,你可以使用单行代码 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 值来覆盖文件名。