Est-il possible de changer le nom de fichier d'un fichier téléchargé dans Django? J'ai cherché, mais je n'ai trouvé aucune réponse.
Mon exigence est que chaque fois qu'un fichier est téléchargé, son nom doit être modifié dans le format suivant.
format = userid + transaction_uuid + file_extension
Merci beaucoup...
Comment chargez-vous le fichier? Je suppose avec le FileField
.
La documentation de FileField.upload_to indique que le champ upload_to
,
peut également être un objet appelable, tel qu'une fonction, qui sera appelée pour obtenir le chemin de téléchargement, y compris le nom du fichier. Cet objet appelable doit pouvoir accepter deux arguments et renvoyer un chemin de type Unix (avec des barres obliques) à transmettre au système de stockage. Les deux arguments qui seront passés sont:
" instance ": instance du modèle dans laquelle la variable
FileField
est définie. Plus spécifiquement, il s'agit de l'instance particulière où le fichier en cours est attaché." nom_fichier ": nom de fichier initialement attribué au fichier. Cela peut être pris en compte ou non lors de la détermination du chemin de destination final.
Il semble donc que vous ayez juste besoin de créer une fonction pour gérer votre nom et renvoyer le chemin.
def update_filename(instance, filename):
path = "upload/path/"
format = instance.userid + instance.transaction_uuid + instance.file_extension
return os.path.join(path, format)
Vous devez avoir une FileField
avec le upload_to
qui appelle un rappel, voir [1].
Votre callback doit appeler une méthode wrapper qui obtient une instance sous l’un des paramètres et nom-fichier l’autre. [2]
Changez-le comme vous le souhaitez et renvoyez le nouveau chemin [3]
FileField(..., upload_to=method_call(params),....)
def method_call(params):
return u'abc'
def wrapper(instance, filename):
return method
c'est la méthode de rappeur dont vous avez besoin pour obtenir l'instance.
def wrapper(instance, filename):
... Your logic
...
return wrapper
def path_and_rename(path, prefix):
def wrapper(instance, filename):
ext = filename.split('.')[-1]
project = "pid_%s" % (instance.project.id,)
# get filename
if instance.pk:
complaint_id = "cid_%s" % (instance.pk,)
filename = '{}.{}.{}.{}'.format(prefix, project, complaint_id, ext)
else:
# set filename as random string
random_id = "rid_%s" % (uuid4().hex,)
filename = '{}.{}.{}.{}'.format(prefix, project, random_id, ext)
# return the whole path to the file
return os.path.join(path, filename)
return wrapper
sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500,
help_text="Browse a file")
J'espère que cela t'aides. Merci.
si vous voulez que votre fonction soit réutilisable:
import hashlib
import datetime
import os
from functools import partial
def _update_filename(instance, filename, path):
path = path
filename = "..."
return os.path.join(path, filename)
def upload_to(path):
return partial(_update_filename, path=path)
Vous devez juste l'utiliser de cette façon:
document = models.FileField(upload_to=upload_to("my/path"))
Le moyen de base est
import os
os.rename('a.txt', 'b.html')
Pour votre situation, cela ressemblerait probablement à
os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))