2013-12-19 76 views
2

只是一個字段這是我的models.py:Overiding節省在Django

class College(models.Model): 
    name = models.CharField(unique=True, max_length=50, 
    help_text='Name of the college.' 
) 
    slug = models.SlugField(unique=True) 
    description = models.TextField(blank = True) 
    image = models.ImageField(upload_to='site-media/media/college_images/', 
    default = 'site-media/media/college_images/default.jpeg' 
) 
    user = models.ForeignKey(User) 


    def get_absolute_url(self): 
    return "/%s/" % self.slug 

    def create_thumbnail(self): 
    if not self.image: 
     return 

    THUMBNAIL_SIZE = (250,193) 

    image = Image.open(StringIO(self.image.read())) 
    thumb = ImageOps.fit(image, THUMBNAIL_SIZE, Image.ANTIALIAS) 
    temp_handle = StringIO() 
    thumb.convert('RGB').save(temp_handle, 'jpeg') 
    temp_handle.seek(0) 

    suf = SimpleUploadedFile(os.path.split(self.image.name)[-1], 
      temp_handle.read(), content_type='image/jpeg') 
    self.image.save('%s_college_.%s'%(os.path.splitext(suf.name)[0],'jpeg'), suf, save=False) 

    def save(self, *args, **kwargs): 
    self.slug = slugify(self.name) 
    self.create_thumbnail() 

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

我已經呈現給用戶一個表單編輯只是描述。當描述'POST'被創建時,上面的'save()'方法被調用。問題在於縮略圖每次都會以一個更大的名字反覆創建。而且,前一個縮略圖也不會從硬盤上刪除。是否有可能,這個'縮略圖'方法在'description'的每個編輯中都不會被反覆調用。

+0

從'save'中重新創建'create_thumbnail'並在需要時手動調用它有什麼問題嗎? – kalhartt

+0

以及我沒有嘗試,因爲我希望每次創建College實例時都要調用它。 – toothie

+0

當你保存一個新的'College'實例時,你只想調用'create_thumbnail'嗎? –

回答

3

您可以檢查您是否在請求發送或不發送圖像文件。爲此,您需要打電話給你,鑑於保存像一個參數要求:college.save(請求)

def save(self, request=False, *args, **kwargs): 
    self.slug = slugify(self.name) 

    if request and request.FILES.get('image',False): 
     self.create_thumbnail() 

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

OR 你可以區分你的保存和使​​用

if self.pk is not None 

修改,但它可以創建問題,如果你編輯你的形象。

所以它的你的選擇你想如何去用它。

+0

如果OP想要使用管理員或任何可以在視圖外調用'save'的代碼,這真的不可行。 –

+0

第一個工作已經完成了我的工作。我會告訴你是否有任何問題。 – toothie

+0

如果你想用這樣的東西,直接從視圖中調用'create_thumbnail',而不是覆蓋'save'方法。 –

1

我看到有兩條合理的路徑來處理這個問題。兩者都不是理想的,所以我會有興趣看看是否有人有更好的選擇。

一種是將您爲其創建縮略圖的最新圖像的文件名保存爲模型字段。然後在您的保存方法中,您可以根據它檢查您的image字段的文件名,並創建一個新的縮略圖(如果它已更改)。這具有需要新模型領域的缺點,但在其應用中更普遍。

另一個是覆蓋表單類的save方法。然後,您可以查看self.instance.image並將其與self.cleaned_data['image']進行比較,以檢查舊圖像文件名。這具有僅影響使用該表單類的視圖的缺點,但不需要更改數據模型。如果您正在使用自定義表單,則可以將自定義表單傳遞給管理員,也可以覆蓋管理類的方法save_model

0

簡單的解決方法就是不要試圖在此階段創建縮略圖,但只有當它的需要,即(僞代碼示例):

class Whatever(models.Model): 
    image = models.ImageField(...) 

    @property 
    def thumbnail(self): 
     thumb = do_i_have_a_thumbnail_yet(self.image) 
     if not thumb: 
      thumb = ok_then_make_me_a_thumbnail_and_store_it_please(self.image) 
     return thumb 

實施do_i_have_a_thumbnail_yet()ok_then_make_me_a_thumbnail_and_store_it_please()就留給讀者做練習,但有些館藏或django應用程序提供此類服務。

另一個 - 甚至更好的imho解決方案是將縮略圖處理委託給模板標籤或模板過濾器。爲什麼?因爲

  1. 縮略圖大多呈現的東西,不屬於該模型
  2. 大部分的時間,你會從相同的圖像需要不同大小的縮略圖
  3. 前端開發者可能要自由更改縮略圖的大小,而不必要求您更改後端代碼並編寫遷移腳本來重新計算所有現有縮略圖。