Применять уникальные имена файлов загрузки с помощью django?
каков наилучший способ переименования фотографий с уникальным именем файла на сервере по мере их загрузки, используя django? Я хочу убедиться, что каждое имя используется только один раз. Есть ли какие-либо приложения pinax, которые могут это сделать, возможно, с GUID?
5 ответов
используйте 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'))
до Django 1.6.6, 1.5.9 и 1.4.14,get_avaialable_name
функция автоматически даст файлам уникальное имя, добавив подчеркивание. Так, например, если вы сохраните один файл " test.jpg", а затем другой файл, " тест.jpg " на ваш сервер, первый будет называться test.jpg, а второй будет называться test_1.формат jpg.
увы, это оказывается вектором для DDOSing машины, отправляя ему тысячи файлов с нулевым байтом для хранения, каждый из которых проверяет тысячи предыдущие файлы, чтобы увидеть, что его имя должно быть.
а вы см. в документах новая система добавляет семь случайных цифр после символа подчеркивания, чтобы исправить эту проблему.
лучший способ может использовать общий класс в вашем 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'))
Ref: https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites
Как насчет объединения имени файла с датой / временем загрузки фотографии, а затем с помощью hashlib создать дайджест сообщения? Это должно дать вам уникальные имена.
в качестве альтернативы вы можете повторно использовать аккуратный маленький фрагмент, который создает уникальные имена и затем использовать полный путь к этому файлу в качестве входных данных для хеш-звонок. Это дает вам уникальные строки постоянной длины, которые вы можете сопоставить с вашими файлами.
на момент написания этого ответа, кажется, вам больше не нужно делать ничего особенного, чтобы это произошло. Если вы настроили поле FileField со статическим свойством upload_to, система хранения Django будет автоматически управлять именованием, так что при загрузке дубликата имени файла Django будет случайным образом генерировать новое уникальное имя файла для дубликата.
работает на Django 1.10.