2010-06-02 49 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