Django: ¿Cómo guardar el nombre del archivo original en FileField?

Quiero que los nombres de archivo sean aleatorios y, por lo tanto, uso la función upload_to que devuelve un nombre de archivo aleatorio como:

 from uuid import uuid4 import os def get_random_filename(instance, filename): ext = filename.split('.')[-1] filename = "%s.%s" % (str(uuid4()), ext) return os.path.join('some/path/', filename) # inside the model class FooModel(models.Model): file = models.FileField(upload_to=get_random_filename) 

Sin embargo, me gustaría guardar el nombre del archivo original en un atributo dentro del modelo. Algo como esto no funciona:

 def get_random_filename(instance, filename): instance.filename = filename ext = filename.split('.')[-1] filename = "%s.%s" % (str(uuid4()), ext) return os.path.join('some/path/', filename) # inside the model class FooModel(models.Model): file = models.FileField(upload_to=get_random_filename) filename = models.CharField(max_length=128) 

¿Cómo puedo hacerlo?

Gracias.

El código publicado normalmente funciona, tal vez el código real sea

 class FooModel(models.Model): filename = models.CharField(max_length=128) file = models.FileField(upload_to=get_random_filename) 

Tenga en cuenta el cambio de orden de los campos anteriores.

Esto no funcionará porque: el upload_to() es invocado por el pre_save() , aquí en el código , cuando se requiere el valor real del FileField . Podría encontrar que la asignación al filename de filename del atributo en la upload() es posterior a la generación del primer filename de filename param en el sql de inserción. Por lo tanto, la asignación no tiene efecto en el SQL generado y solo afecta a la instancia en sí.

Si ese no es el problema, publique el código que escribió en shell.

Puede seguir la ruta de llenado del nombre de archivo durante el proceso de guardado. Obviamente, tendrá que almacenar el nombre del archivo original en la memoria cuando se ejecute su get_random_filename.

 # inside the model class FooModel(models.Model): file = models.FileField(upload_to=get_random_filename) filename = models.CharField(max_length=128) def save(self, force_insert=False, force_update=False): super(FooModel, self).save(force_insert, force_update) #Do your code here... 

Sólo reordenar sus comandos. https://docs.djangoproject.com/en/dev/topics/db/models/

 def save(self, *args, **kwargs): do_something() super(Blog, self).save(*args, **kwargs) # Call the "real" save() method. do_something_else()