Quelle est la meilleure façon de renommer des photos avec un nom de fichier unique sur le serveur lors de leur téléchargement, à l'aide de django? Je veux m'assurer que chaque nom n'est utilisé qu'une seule fois. Y a-t-il des applications pinax qui peuvent le faire, peut-être avec GUID?
Utilisez uuid. Pour lier cela à votre modèle, voir documentation Django 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 FileField/ImageField, spécifiez get_file_path
comme upload_to
valeur.
file = models.FileField(upload_to=get_file_path,
null=True,
blank=True,
verbose_name=_(u'Contact list'))
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 dans toutes 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 puis, dans votre modèle, importez simplement la classe d'assistance:
from mymodule.helpers import RandomFileName
Et puis utilisez-le:
logo = models.ImageField(upload_to=RandomFileName('logos'))
Réf: https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites
Avant Django 1.6.6, 1.5.9 et 1.4.14, le get_avaialable_name
la fonction donnerait automatiquement aux fichiers un nom unique en ajoutant un trait de soulignement. Ainsi, par exemple, si vous enregistrez un fichier "test.jpg" puis un autre fichier "test.jpg" sur votre serveur, le premier sera appelé test.jpg et le second sera appelé test_1.jpg.
Hélas, cela s'avère être un vecteur pour DDOSer une machine, en lui envoyant des milliers de fichiers de zéro octet à stocker, chacun vérifiant des milliers de fichiers précédents pour voir quel devrait être son nom.
Comme vous le ferez voir dans la documentation , le nouveau système ajoute sept chiffres aléatoires après le trait de soulignement pour résoudre ce problème.
Au moment de la rédaction de cette réponse, il semble que vous n'ayez plus rien à faire de spécial pour que cela se produise. Si vous configurez un FileField avec une propriété upload_to statique, le système de stockage Django gérera automatiquement la dénomination de sorte que si un nom de fichier en double est téléchargé, Django sera aléatoire générer un nouveau nom de fichier unique pour le doublon.
Fonctionne sur Django 1.10.
Vous pouvez écrire votre propre FileField
et écraser generate_filename
.
Par exemple:
class UniqueNameFileField(FileField):
def generate_filename(self, instance, filename):
_, ext = os.path.splitext(filename)
name = f'{uuid.uuid4().hex}{ext}'
return super().generate_filename(instance, name)
Que diriez-vous de concaténer le nom de fichier avec la date/heure à laquelle la photo a été téléchargée, puis d'utiliser hashlib pour créer un résumé de message? Cela devrait vous donner des noms de fichiers uniques.
Alternativement, vous pouvez réutiliser n petit extrait soigné qui crée des noms de fichiers uniques, puis utiliser le chemin d'accès complet à ce fichier comme entrée pour votre appel de hachage. Cela vous donne des chaînes uniques de longueur constante que vous pouvez mapper à vos fichiers.
Django applique automatiquement un nom de fichier unique. si le fichier existe déjà, sept caractères uniques sont ajoutés au nom de fichier
testé sur Django 2.2