2012-06-05 33 views
11

Quiero los nombres de archivo a ser al azar y por lo tanto yo uso upload_to función que devuelve un nombre de archivo al azar de este modo:Django: ¿Cómo guardar el nombre de archivo original en FileField?

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 de archivo original a 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.

+0

Funciona perfectamente bien en mis pruebas. ¿Cómo exactamente no funciona para usted? ¿Lo que pasa? Tal vez el problema está en el código de vista? – rantanplan

+0

una vez que hace esto y consulta el objeto desde db, ¿todavía ve el valor de nombre de archivo? – miki725

+0

Sí. De hecho, lo probé dentro del caparazón. Lo maté, lo lancé de nuevo y el nombre de archivo estaba allí. En realidad, al principio pensé que simplemente te olvidaste de hacer un 'instance.save()' dentro de get_random_filename. Pero parece que no es necesario. – rantanplan

Respuesta

8

El código publicado funciona con normalidad, tal vez el código real es

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

nota el cambio del orden de los campos anteriores.

Esto no funcionará porque: el upload_to() es invocada por la pre_save(), here in the code, cuando se requiere que el valor real de la FileField. Puede encontrar que la asignación al atributo filename en el upload() es posterior a la generación del primer parámetro filename 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.

+0

Eso fue correcto en el acto. Volví a escribir el código central en la pregunta sin darme cuenta de que revertí el orden. ¡¡¡¡¡Muchas gracias!!!!! – miki725

+0

Y gracias por señalar dónde estaba sucediendo eso. Estaba cavando campos y modelos de código pero no pensé en buscar en sql. – miki725

+0

Parece estar roto con el Django 1.5 ... Me vi obligado a agregar 'super (FooModel, self).save (update_fields = ['filename']) 'en mi modelo guardado método anulado. Alguna idea ? – dulaccc

1

Puede ir por la ruta de llenar el nombre del archivo durante el proceso de guardar. Obviamente, deberá 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... 
+0

Lo que no me gusta de esto es que luego debe guardarse twise. Yo preferiría algo más ordenado. – miki725

Cuestiones relacionadas