2012-03-07 2 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 제외하고 잘 작동합니다.

크기가 조정 된 이미지의 실제 크기는 지정된 최대 크기보다 작을 수 있으므로 크기를 조정 한 후 실제 크기를 확인하려면 크기 조정 된 파일을 열어야합니다. 그런 다음 수동으로 banner_widthbanner_height을 설정하고 다시 저장할 수는 있지만 효율적인 방법은 아닙니다. 또한 먼저 크기 조정, 너비 및 높이 필드 설정 및 저장을 수행 할 수 있지만 저장을 수행하기 전에 self.banner.path 위치의 파일이 존재하지 않습니다.

제대로 수행하는 방법에 대한 제안 사항은 무엇입니까?

이제
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]) 

난 그냥 정의 할 수 있습니다 :

+0

resize_image 메서드의 내용을 게시 할 수 있습니까? 그 방법에서 뭔가 마술이 일어나지 않는 한, 저장하기 전에 banner_width 및 banner_height 속성을 설정하기 위해 이미지의 최종 크기를 결정하는 논리를 사용할 수있는 것처럼 보입니다. –

+0

@CaseyKinsey 최근 크기 변경된 이미지를 반환하도록이 함수를 업데이트했으며, 지금은'save' 메소드에서'super (SomeModel, self) .save()'를 호출 한 다음'resize_image()'를 호출하고'banner_width'와' banner_height'를 호출하고 마지막으로'super (SomeModel, self) .save()'를 다시 호출합니다. 모델 인스턴스를 두 번 저장하는 것을 피하고 싶지만 작동합니다. – Dzejkob

답변

3

효율적으로이 일을하려고 몇 시간 후, 나는이 문제에 나의 접근 방식을 변경하고 같은 CustomImageField을 정의한

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 인수에 따라 업로드 후 이미지의 크기가 자동으로 조정되고 너비/높이 필드가 올바르게 업데이트되어 개체를 두 번 저장하지 않아도됩니다. 빠른 테스트 후 제대로 작동하는 것 같습니다.