Принудительно использовать уникальные имена файлов для загрузки, используя django? - PullRequest
49 голосов
/ 20 апреля 2010

Какой лучший способ переименовать фотографии с уникальным именем файла на сервере, когда они загружаются, используя django?Я хочу убедиться, что каждое имя используется только один раз.Существуют ли приложения Pinax, которые могут сделать это, возможно, с GUID?

Ответы [ 5 ]

126 голосов
/ 20 апреля 2010

Используйте 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'))
10 голосов
/ 24 октября 2016

Лучшим способом может быть использование общего класса в вашем 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

9 голосов
/ 20 апреля 2010

До Django 1.6.6, 1.5.9 и 1.4.14 функция get_avaialable_name автоматически давала файлам уникальное имя, добавляя подчеркивание. Так, например, если вы сохраните один файл «test.jpg», а затем другой файл «test.jpg» на своем сервере, первый будет называться test.jpg, а второй будет называться test_1.jpg.

Увы, это оказывается вектором DDOS для машины, посылая ей тысячи файлов нулевого байта для хранения, каждый проверяя тысячи предыдущих файлов, чтобы увидеть, как его имя должно быть.

Как вы увидите в документации , новая система добавляет семь случайных цифр после подчеркивания, чтобы решить эту проблему.

2 голосов
/ 10 апреля 2017

На момент написания этого ответа кажется, что вам больше не нужно делать ничего особенного, чтобы это произошло. Если вы настроите FileField со статическим свойством upload_to, система хранения Django будет автоматически управлять именами, чтобы при загрузке дублированного имени файла Django случайным образом генерировала новое уникальное имя файла для дубликата.

Работает на Django 1.10.

0 голосов
/ 20 апреля 2010

Как насчет объединения имени файла с датой / временем загрузки фотографии и последующим использованием hashlib для создания дайджеста сообщения? Это должно дать вам уникальные имена файлов.

В качестве альтернативы вы можете повторно использовать аккуратный маленький фрагмент , который создает уникальные имена файлов, а затем использовать полный путь к этому файлу в качестве входных данных для вашего хэш-вызова. Это дает вам уникальные строки постоянной длины, которые вы можете сопоставить с вашими файлами.

...