2013-07-01 60 views
0

從Django的驗證函數中修改數據是否合法?我需要自動調整ImageFields的圖像。我們可以在Django的驗證函數中調整ImageField的大小嗎?

在文檔中,它說這些函數應該引起ValidationError,但實際上我需要修改數據(在這種情況下爲image)。我想這樣做,因爲我必須將其應用於多個模型。如果我能做到這一點,我不需要更改管理員中的表單。

def image_field_autoresize(image): 
    if image.width > MAX_IMAGE_WIDTH: 
     raise ValidationError(u'image width error') 
    if image.height > MAX_IMAGE_HEIGHT: 
     raise ValidationError(u'image height error') 
+1

看起來像獨立的事情給我。首先,我會調整模型保存功能的大小,其次,您可以驗證上傳的圖像沒有超出屬於表單/模型驗證的設置大小以符合我的理解。 – Jingo

+0

我不想修改'save'中的圖像尺寸,因爲這不是驗證的最佳位置。我剛剛接受了@ karthikr的回答,你可以在那裏看到討論,以更好地理解我需要什麼以及如何解決它。問候! – Caumons

+0

Hi @Jingo!經過一些測試後,我意識到從一個'clean'方法內部我們不能使用'ImageField'內容來使用PIL來讀取它。所以,我認爲調整大小的最佳位置是'save()'方法,就像你在開始時所說的那樣。由於我需要這個過程是用戶透明的,我不需要實現任何表單驗證。謝謝! (我已經提高了你的評論)。 – Caumons

回答

2

與@karthikr的討論之後,我可以用下面的結論:

如果您需要在驗證過程中更改的數據,可以從ModelForm類中重寫clean_<fieldname>()。在ModelFormclean()方法中,您不應該那樣做。如果你需要做一些圖像調整大小,我發現最好的地方是Model的save()方法。

我已經解決了這個問題是這樣的:

我已經創建了一個名爲image.py新的模塊,它包含一個函數,作爲參數圖像的絕對路徑,實現調整大小的邏輯和修改圖像的大小。在我的情況下,如果寬度大於給定大小,則「調整大小邏輯」會按比例縮小圖像。

from PIL import Image 
from django.conf import settings 


def autoresize_image(image_path): 
    image = Image.open(image_path) 
    width = image.size[0] 
    if width > settings.IMAGE_MAX_WIDTH: 
     height = image.size[1] 
     reduce_factor = settings.IMAGE_MAX_WIDTH/float(width) 
     reduced_width = int(width * reduce_factor) 
     reduced_height = int(height * reduce_factor) 
     image = image.resize((reduced_width, reduced_height), Image.ANTIALIAS) 
     image.save(image_path) 

我在包含要調整的ImageField模型調用這個函數從save()方法。要記住這裏:在嘗試調整圖像大小之前先撥super(),否則它將不會被發現,因爲它不會保存在您的硬盤中,並且如果不需要ImageField,請檢查是否給出了值。它看起來像:

def save(self, *args, **kwargs): 
    super(Startup, self).save(*args, **kwargs) 
    if self.logo: 
     autoresize_image(self.logo.path) 

感謝@Jingo以及他的評論。這是非常有用的:)

+0

很好地解釋了 – karthikr

+0

@karthikr謝謝! :) – Caumons

相關問題