【问题标题】:How to change the file name of an uploaded file in Django?如何在 Django 中更改上传文件的文件名?
【发布时间】:2011-02-10 10:40:02
【问题描述】:

django 可以更改上传文件的文件名吗?我搜索了,但找不到任何答案。

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

format = userid + transaction_uuid + file_extension

非常感谢...

【问题讨论】:

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


    【解决方案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", "{id}{uuid}.{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值来覆盖文件名。

          【讨论】:

          • 请将代码部分作为代码格式而不是文本格式插入
          猜你喜欢
          • 2012-05-13
          • 2013-02-14
          • 2013-07-10
          • 2012-02-02
          • 1970-01-01
          • 2016-05-28
          • 1970-01-01
          • 2012-06-02
          • 1970-01-01
          相关资源
          最近更新 更多