2010-06-02 68 views
4

很多時候我需要在使用它之前過濾一些表單數據(保存到數據庫等)。假設我想剝離空格並用一個單獨的空格代替重複的空格的文本字段,有許多形式。這並不難做到這一點使用clean_<fieldname>方法:Django:如何清理表單字段並避免代碼重複

# Simplified model with two text fields 
class MyModel(models.Model): 
    title = models.CharField() 
    description = models.CharField() 

# Model-based form 
class MyForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 

    def clean_title(self): 
     title = self.cleaned_data['title'] 
     return re.sub(r'\s{2,}', ' ', title.strip()) 

    def clean_description(self): 
     description = self.cleaned_data['description'] 
     return re.sub(r'\s{2,}', ' ', description.strip()) 

這不正是我需要的,並具有很好的副作用,我想:如果用戶僅輸入空格,該領域將被視爲空的,因此是無效的(如果它是必需的),我甚至不必投擲ValidationError

這裏顯而易見的問題是代碼重複。就算我會創造一些功能,比如說my_text_filter,我會叫它爲每個文本字段在我的所有形式:

from myproject.filters import my_text_filter 

class MyForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 

    def clean_title(self): 
     return my_text_filter(self.cleaned_data['title']) 

    def clean_description(self): 
     return my_text_filter(self.cleaned_data['description']) 

的問題:是否有在Django(任何標準和簡單的方法我使用版本1.2(如果重要的話))(例如,通過將屬性validators = {'title': my_text_filter, 'description': my_text_filter}添加到MyModel),或者至少有一些或多或少的標準解決方法?我已經閱讀了文檔中的表單驗證和驗證器,但在那裏找不到我需要的。

+1

如果你想要做一次,你可以使用,而不是寫一個針對每一領域的'clean' mehod東西給多個字段! – 2010-06-02 19:17:20

回答

2

正如我所知Django沒有任何本地解決方案來解決你的問題。 我只能表明我是如何解決這個問題的。 我建議你爲ModelForm使用decorator。 這裏的工作代碼(也是我使用記錄模塊):

#DECORATOR 
def applyValidators(model_form): 
    def apply(*args,**kwargs): 
     try: 
      if hasattr(model_form.Meta.model,"validators"): 
       for field_name,fnc in model_form.Meta.model.validators.items(): 
        setattr(model_form,"clean_%s" % field_name,fnc) 
     except Exception,err: 
      logging.error(str(err)) 
     return model_form(*args,**kwargs) 
    return apply 

#VALIDATORS 
def validator(*args,**kwargs): 
    return "SOMEVALUE" 

#MODEL 
class MyModel(models.Model): 
    #Your fields 
    ....... 
    ....... 
    ....... 

    #VALIDATE DICT 
    validators = {"username":validator,"email":validator}  

#MODEL FORM 
@applyValidators 
class MyModelForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 
    ....... 
    ....... 
    ....... 
+0

非常好用的裝飾。請記住這一點。 – 2011-02-01 14:56:45