2011-10-25 14 views
10

Poniższy kod wykonuje zdjęcie po to zostaje zapisany i sprawia miniaturę z niego:Django - Zapisywanie obrazu ręcznie do pola 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 

To działa dobrze, obraz oryginału + miniaturka są zarówno przesyłane, a do obrazu przypisywana jest właściwa ścieżka.

Jedyny problem polega na tym, że miniatury nie przypisuje się ścieżki nowo utworzonej miniatury - jest ona pusta w bazie danych. Czytałem dokumentację, i wygląda na to, czy zapisać miniatury z zaoszczędzić = True powinno rozwiązać mój problem:

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

Jednak ten sposób podnosi następujące:

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

mogę nie rozumiem, co robię źle.

Odpowiedz

6

Mam rozwiązać mój problem po prostu przesuwając:

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

do koniec def zapisać(). Nadal nie jestem pewien, dlaczego tak się dzieje, ale moim jedynym wytłumaczeniem jest to, że save() samo w sobie utrzymuje wartości pól w bazie danych i dlatego musi zostać wykonane na samym końcu.

2

Spróbuj przejść rzeczywistej zawartości pliku zamiast obiektu 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

Próbowałem już, daje następujący błąd: Typ wyjątku: \t AttributeError Wartość wyjątku: obiekt "str" ​​nie ma atrybutu "porcje" – abstractpaper

Powiązane problemy