2012-03-07 64 views
1

我有一個模型包含ImageField應該在上傳後調整大小。ImageField調整大小保存也更新width_field和height_field

class SomeModel(models.Model): 
    banner = ImageField(upload_to='uploaded_images', 
         width_field='banner_width', 
         height_field='banner_height') 
    banner_width = models.PositiveIntegerField(_('banner width'), editable=False) 
    banner_height = models.PositiveIntegerField(_('banner height'), editable=False) 

def save(self, *args, **kwargs): 
    super(SomeModel, self).save(*args, **kwargs) 
    resize_image(filename=self.banner.path, 
       width=MAX_BANNER_WIDTH, 
       height=MAX_BANNER_HEIGHT) 

resize_image是一個自定義函數做調整大小,和一切工作正常,除了banner_width和banner_height被填充了原始圖像的尺寸,調整前。

調整大小的圖像的實際尺寸可能小於給定的MAX值,所以我必須打開調整大小的文件以在調整大小後檢查它的實際尺寸。然後我可以手動設置banner_widthbanner_height,並再次保存,但這不是有效的方法。 我也可以先調整大小,設置寬度和高度字段,然後保存,但在執行保存之前,位置self.banner.path處的文件不存在。

有關如何正確完成此任務的任何建議?

+0

你可以發佈resize_image方法的內容嗎?看起來你可以使用一些邏輯確定圖像的最終大小,在保存之前設置banner_width和banner_height屬性,除非在該方法中發生了某些魔術。 – 2012-03-07 22:39:33

+0

@CaseyKinsey我最近更新了這個函數來返回調整大小的圖像,現在在'save'方法中,我首先調用'super(SomeModel,self).save()'然後執行'resize_image()',更新'banner_width'和' banner_height',最後再次調用'super(SomeModel,self).save()'。它的工作原理,雖然我想避免兩次保存模型實例。 – Dzejkob 2012-03-08 09:11:08

回答

3

幾個小時的努力有效地做到這一點之後,我改變了我的辦法處理這一問題,並定義CustomImageField這樣的:

class CustomImageField(ImageField): 
    attr_class = CustomImageFieldFile 

    def __init__(self, resize=False, to_width=None, to_height=None, force=True, *args, **kwargs): 
     self.resize = resize 
     if resize: 
      self.to_width = to_width 
      self.to_height = to_height 
      self.force = force 
     super(CustomImageField, self).__init__(*args, **kwargs) 


class CustomImageFieldFile(ImageFieldFile): 

    def save(self, name, content, save=True): 
     super(CustomImageFieldFile, self).save(name, content, save=save) 
     if self.field.resize: 
      resized_img = resize_image(filename=self.path, 
             width=self.field.to_width, 
             height=self.field.to_height, 
             force=self.field.force) 
      if resized_img: 
       setattr(self.instance, self.field.width_field, resized_img.size[0]) 
       setattr(self.instance, self.field.height_field, resized_img.size[1]) 

現在就可以定義:

class SomeModel(models.Model): 
    my_image = CustomImageField(resize=True, to_width=SOME_WIDTH, to_height=SOME_HEIGHT, force=False, 
           width_field='image_width', height_field='image_height') 
    image_width = models.PositiveIntegerField(editable=False) 
    image_height = models.PositiveIntegerField(editable=False) 

而且根據resize參數,圖像可以在上傳後自動調整大小,並且寬度/高度字段可以正確更新,而無需保存對象兩次。經過快速測試,似乎工作正常。

相關問題