¿Cómo cambiar el nombre de archivo de un archivo cargado en Django?

¿Es posible cambiar el nombre de archivo de un archivo cargado en django? Busqué, pero no pude encontrar ninguna respuesta.

Mi requisito es que cada vez que se cargue un archivo, su nombre de archivo debe cambiarse en el siguiente formato.

format = userid + transaction_uuid + file_extension 

Muchas gracias…

¿Cómo estás subiendo el archivo? Asumo con el FileField .

La documentación para FileField.upload_to dice que el campo upload_to ,

También puede ser un llamable, como una función, que se llamará para obtener la ruta de carga, incluido el nombre de archivo. Este llamable debe ser capaz de aceptar dos argumentos y devolver una ruta de estilo Unix (con barras diagonales) para que se transmita al sistema de almacenamiento. Los dos argumentos que se pasarán son:

instancia “: una instancia del modelo donde se define FileField . Más específicamente, esta es la instancia particular donde se está adjuntando el archivo actual.

nombre de archivo “: el nombre de archivo que originalmente se le dio al archivo. Esto puede o no puede ser tenido en cuenta al determinar la ruta de destino final.

Así que parece que solo necesitas hacer una función para manejar tu nombre y devolver la ruta.

 def update_filename(instance, filename): path = "upload/path/" format = instance.userid + instance.transaction_uuid + instance.file_extension return os.path.join(path, format) 

FileField tener un FileField con el upload_to que llama a una callback, vea [1]

Su callback debe llamar a un método de envoltura que obtiene una instancia como uno de los parámetros y el nombre de archivo como el otro. [2]

Cámbiala como quieras y devuelve el nuevo camino [3]

1. LOGICA

 FileField(..., upload_to=method_call(params),....) 

2. definir método

 def method_call(params): return u'abc' 

3. Envoltura:

 def wrapper(instance, filename): return method 

Este es el método rapero que necesitas para obtener la instancia.

 def wrapper(instance, filename): ... Your logic ... return wrapper 

Código Completo

 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 

Llamar al Método

 sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500, help_text="Browse a file") 

Espero que esto ayude. Gracias.

Si quieres que tu función sea reutilizable:

 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) 

Solo tienes que usarlo de esta manera:

 document = models.FileField(upload_to=upload_to("my/path")) 

La forma básica es

 import os os.rename('a.txt', 'b.html') 

Para su situación, probablemente se vería como

 os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))