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?
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'))
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.
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
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.
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.