我有一个带有Django Rest Framework的API端点来上传图像。
class MyImageSerializer(serializers.ModelSerializer):
image = serializers.ImageField(source='image')
我可以上传图片,但是会使用从客户端发送的文件名保存,这可能会导致冲突。我想将文件上传到带有时间戳文件名的CDN。
生成文件名不是问题,只需用它保存图像。
任何人都知道该怎么做? 感谢。
答案 0 :(得分:5)
如果您的图片来自django的ImageField类型,那么您根本不需要做任何事情,甚至不像您那样在序列化程序中声明它。将它添加到 fields 属性中就足够了,django将处理冲突。这意味着django会在每个可能产生冲突的新文件上添加 _index ,所以如果你上传一个名为'my_pic.jpg'的文件5次,你实际上会有文件'my_pic.jpg','你的服务器上有my_pic_1.jpg','my_pic_2.jpg','my_pic_3.jpg','my_pic_4.jpg'。
现在,这是使用django的FileSystemStorage实现(请参阅here)完成的,但如果您希望它为您的文件名附加时间戳,您所要做的就是编写一个存储类来覆盖< em> get_available_name(name)方法。例如:
class MyFileSystemStorage(FileSystemStorage):
def get_available_name(self, name):
''' name is the current file name '''
now = time.time()
stamp = datetime.datetime.fromtimestamp(now).strftime('%Y-%m-%d-%H-%M-%S')
return '{0}_{1}'.format(name, str(stamp))
模型中的图像字段:
image = models.ImageField(upload_to='your upload dir', storage= MyFileSystemStorage)
自2014年8月20日起,这不再是一个问题,因为Django found a vulnerability related to this behaviour(感谢@mlissner指出它)。重要摘录:
我们通过更改生成文件的算法来解决问题 如果已存在具有上载名称的文件,则为name。 Storage.get_available_name()现在附加下划线加随机7 字符字母数字字符串(例如“_x3a1gho”),而不是迭代 通过下划线后跟一个数字(例如“_1”,“_ 2”等)。