如何在Django中强制上传文件名唯一?
在使用Django上传照片时,怎么才能给每张照片起一个独一无二的名字呢?我想确保每个名字只用一次。有没有什么Pinax应用可以做到这一点,可能是用GUID(全局唯一标识符)来实现?
7 个回答
12
在写这个回答的时候,似乎你不需要做什么特别的事情就能实现这个功能。如果你设置一个 FileField
,并给它一个固定的 upload_to
属性,Django 的存储系统会自动处理文件命名的问题。也就是说,如果有人上传了一个重复的文件名,Django 会随机生成一个新的独特文件名来避免冲突。
这个功能在 Django 1.10 版本上有效。
20
一个更好的方法是使用你在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)
然后在你的模型中,只需导入这个助手类:
from mymodule.helpers import RandomFileName
接着就可以使用它了:
logo = models.ImageField(upload_to=RandomFileName('logos'))
参考链接:https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites
168
使用uuid。要将其与您的模型结合起来,可以查看Django文档中关于FileField的upload_to部分。
例如,在您的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)
然后,在定义您的FileField/ImageField时,将get_file_path
指定为upload_to
的值。
file = models.FileField(upload_to=get_file_path,
null=True,
blank=True,
verbose_name=_(u'Contact list'))