使用django强制使用唯一的上传文件名?

zjm*_*126 52 python django file-rename pinax

使用django上传服务器时,使用唯一文件名重命名照片的最佳方法是什么?我想确保每个名称只使用一次.是否有任何pinax应用程序可以做到这一点,也许与GUID?

Nat*_*han 130

使用uuid.要将其与您的模型联系起来,请参阅FileField upload_to的Django文档.

例如,在models.py中定义以下函数:

import uuid
import os

def get_file_path(instance, filename):
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (uuid.uuid4(), ext)
    return os.path.join('uploads/logos', filename)
Run Code Online (Sandbox Code Playgroud)

然后,在定义FileField/ImageField时,指定get_file_pathupload_to值.

file = models.FileField(upload_to=get_file_path,
                        null=True,
                        blank=True,
                        verbose_name=_(u'Contact list'))
Run Code Online (Sandbox Code Playgroud)

  • @Creotiv这不是改变上传路径,而是用UUID替换文件名.这不应该导致任何迁移问题. (8认同)
  • 这样做是一个错误的决定,因为您将在此字段上进行无限次迁移,导致每次迁移时您将具有不同的上载路径。 (2认同)
  • @Creotiv - 不,迁移仅跟踪*如何*生成文件名.这意味着迁移知道正在使用一个名为`get_file_path`的函数.如果使用`upload_to = uuid4()`,那就是你所说的问题发挥作用的情况. (2认同)

Rap*_*tor 12

更好的方法是在helpers.py中使用公共类.这样您就可以在应用程序中重用随机文件生成器.

在你的helpers.py中:

import os
import uuid
from django.utils.deconstruct import deconstructible


@deconstructible
class RandomFileName(object):
    def __init__(self, path):
        self.path = os.path.join(path, "%s%s")

    def __call__(self, _, filename):
        # @note It's up to the validators to check if it's the correct file type in name or if one even exist.
        extension = os.path.splitext(filename)[1]
        return self.path % (uuid.uuid4(), extension)
Run Code Online (Sandbox Code Playgroud)

然后在你的模型中导入辅助类:

from mymodule.helpers import RandomFileName 
Run Code Online (Sandbox Code Playgroud)

然后使用它:

logo = models.ImageField(upload_to=RandomFileName('logos'))
Run Code Online (Sandbox Code Playgroud)

参考:https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites


mli*_*ner 10

在Django 1.6.6,1.5.9和1.4.14之前,该get_avaialable_name函数会通过添加下划线自动为文件指定唯一名称.因此,例如,如果您将一个文件"test.jpg"和另一个文件"test.jpg"保存到您的服务器,第一个将被称为test.jpg,第二个将被称为test_1.jpg.

唉,结果是DDOS一台机器的向量,通过发送数千个零字节文件进行存储,每个文件检查数千个以前的文件,看看它的名字应该是什么.

正如您在文档中看到的那样,新系统在下划线后面附加七个随机数字来解决此问题.


M. *_*yan 6

在撰写此答案时,您似乎不再需要做任何特别的事情来实现这一目标。如果你设置了一个FileField静态upload_to属性,Django 存储系统会自动管理命名,这样如果上传重复的文件名,Django 会随机生成一个新的唯一文件名。

适用于 Django 1.10。

  • 确认这在 Django 2.1 中仍然有效。这是在默认存储类中自动完成的。请参阅[get_available_name](https://docs.djangoproject.com/en/stable/ref/files/storage/#django.core.files.storage.Storage.get_available_name)。 (2认同)