Appliquer les noms de fichier de téléchargement uniques en utilisant django?

Quelle est la meilleure façon de renommer des photos avec un nom de fichier unique sur le serveur lorsqu'elles sont téléchargées, en utilisant django? Je veux m'assurer que chaque nom est utilisé qu'une seule fois. Y a-t-il des applications pinax qui peuvent faire cela, peut-être avec GUID?

45
demandé sur Jeff Atwood 2010-04-20 12:30:56

5 réponses

utiliser uuid. Pour relier cela à votre modèle, voir Django documentation pour FileField upload_to.

par exemple dans votre models.py définissez la fonction suivante:

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)

ensuite, lors de la définition de votre champ FileField/ImageField, spécifiez get_file_path comme la valeur upload_to .

file = models.FileField(upload_to=get_file_path,
                        null=True,
                        blank=True,
                        verbose_name=_(u'Contact list'))
118
répondu Nathan 2014-01-18 05:09:41

avant Django 1.6.6, 1.5.9, et 1.4.14, la fonction get_avaialable_name donnerait automatiquement aux fichiers un nom unique en ajoutant un caractère de soulignement. Ainsi, par exemple, si vous enregistrez un fichier "test."jpg" et puis un autre fichier "test."jpg" à votre serveur, le premier sera appelé test.jpg, et le second sera appelé test_1.jpg.

hélas, qui s'avère être un vecteur pour DDOSing une machine, en lui envoyant des milliers de fichiers zéro octet à stocker, chaque un qui vérifie des milliers de fichiers précédents pour voir quel devrait être son nom.

vous pourrez voir dans les docs , le nouveau système ajoute sept chiffres aléatoires après le trait de soulignement pour résoudre ce problème.

5
répondu mlissner 2015-07-06 21:17:56

une meilleure façon pourrait être d'utiliser une classe commune dans votre helpers.py. De cette façon, vous pouvez réutiliser le générateur de fichiers aléatoires à travers vos applications.

dans votre 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)

et ensuite dans votre modèle il suffit d'importer la classe helper:

from mymodule.helpers import RandomFileName 

et ensuite l'utiliser:

logo = models.ImageField(upload_to=RandomFileName('logos'))

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

5
répondu Raptor 2016-10-24 00:38:23

Que Diriez-vous de concaténer le nom du fichier avec la date / heure à laquelle la photo a été téléchargée et d'utiliser hashlib pour créer un condensé de messages? Cela devrait vous donner des noms de fichiers uniques.

alternativement vous pouvez réutiliser un petit snippet qui crée des noms de fichiers uniques et puis utiliser le chemin complet vers ce fichier comme entrée à votre appel de hachage. Cela vous donne des chaînes de longueur constante uniques que vous pouvez associer à vos fichiers.

0
répondu Jon Cage 2017-05-23 12:10:22

au moment d'écrire cette réponse, il semble que vous n'ayez plus besoin de faire quoi que ce soit de spécial pour que cela arrive. Si vous configurez un champ de fichiers avec une propriété upload_to statique, le système de stockage Django gérera automatiquement la nommage de sorte que si un nom de fichier dupliqué est téléchargé, Django générera au hasard un nouveau nom de fichier unique pour le dupliqué.

Travaille sur Django 1.10.

0
répondu M. Ryan 2017-04-10 17:50:06