2011-10-25 17 views
10

El siguiente código toma una imagen después de que se guarda y se hace una miniatura de ella:Django - Guardar una imagen de forma manual a un campo ImageField

class Image(models.Model): 
    image  = models.ImageField(upload_to='images') 
    thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False) 

    def save(self, *args, **kwargs): 
     super(Image, self).save(*args, **kwargs) 
     if self.image: 
      from PIL import Image as ImageObj 
      from cStringIO import StringIO 
      from django.core.files.uploadedfile import SimpleUploadedFile 

      try: 
       # thumbnail 
       THUMBNAIL_SIZE = (160, 160) # dimensions 

       image = ImageObj.open(self.image) 

       # Convert to RGB if necessary 
       if image.mode not in ('L', 'RGB'): image = image.convert('RGB') 

       # create a thumbnail + use antialiasing for a smoother thumbnail 
       image.thumbnail(THUMBNAIL_SIZE, ImageObj.ANTIALIAS) 

       # fetch image into memory 
       temp_handle = StringIO() 
       image.save(temp_handle, 'png') 
       temp_handle.seek(0) 

       # save it 
       file_name, file_ext = os.path.splitext(self.image.name.rpartition('/')[-1]) 
       suf = SimpleUploadedFile(file_name + file_ext, temp_handle.read(), content_type='image/png') 

       self.thumbnail.save(file_name + '.png', suf, save=False) 
      except ImportError: 
       pass 

Está funcionando bien, la imagen original + la miniatura son a la vez se está cargando, y se está asignando a la imagen la ruta correcta.

El único problema es que no se está asignando a la miniatura la ruta de la miniatura recientemente creada; está vacía en la base de datos. He leído la documentación, y parece que si salvo la miniatura con save = True debe solucionar mi problema:

self.thumbnail.save(file_name + '.png', suf, save=True) 

Sin embargo, hacer esto es elevar los siguientes:

Django Version: 1.3.1 
Exception Type: IOError 
Exception Value:  
cannot identify image file 

que pueda No entiendo lo que estoy haciendo mal.

Respuesta

6

he resuelto mi problema simplemente moviendo:

super(Image, self).save(*args, **kwargs) 

a la fin de def save(). Todavía no estoy seguro de por qué está sucediendo de esta manera, pero mi única explicación es que save() en sí mismo persiste en los valores de los campos en la base de datos y, por lo tanto, debe ejecutarse al final.

2

intento Pase el contenido real de los archivos en lugar del objeto SimpleUploadedFile:

self.thumbnail.save(file_name + '.png', temp_handle.read(), save=True) 

https://docs.djangoproject.com/en/dev/ref/files/file/#additional-methods-on-files-attached-to-objects how to manually assign imagefield in Django Programmatically saving image to Django ImageField

+0

Lo he intentado ya, da el siguiente error: Tipo de excepción: \t AttributeError Excepción Valor: el objeto 'str' no tiene ningún atributo 'trozos' – abstractpaper

Cuestiones relacionadas