2014-02-16 52 views
14

我有三个相同的SelectField输入形式,每个都有相同的选项集。我不能使用一个多选。我如何验证wtforms字段彼此?

我想确保用户为这三个字段选择三个不同的选择。

在自定义验证中,似乎一次只能引用一个字段,而不会将此字段的值与其他字段的值进行比较。我怎样才能做到这一点?谢谢!

回答

21

您可以在Form覆盖validate ...

class MyForm(Form): 
    select1 = SelectField('Select 1', ...) 
    select2 = SelectField('Select 2', ...) 
    select3 = SelectField('Select 3', ...) 
    def validate(self): 
     if not Form.validate(self): 
      return False 
     result = True 
     seen = set() 
     for field in [self.select1, self.select2, self.select3]: 
      if field.data in seen: 
       field.errors.append('Please select three distinct choices.') 
       result = False 
      else: 
       seen.add(field.data) 
     return result 
+0

谢谢 - 为什么行'如果不是Form.validate(self):'?当我尝试你的建议并且验证不运行时,这会持续发射。 – YPCrumble

+0

这就是默认验证(就像你没有覆盖验证一样) – FogleBird

+0

其他步骤是按照你的要求在多个字段上执行验证。 – FogleBird

0

我写了一个小Python库required,使跨字段验证这样更容易。您可以声明性地将验证逻辑编码为成对依赖关系。所以,你的形式可能看起来像:

from required import R, Requires, RequirementError 

class MyForm(Form): 

    VALIDATION = (
     Requires("select1", R("select1") != R("select2") + 
     Requires("select2", R("select2") != R("select3") + 
     Requires("select3", R("select3") != R("select1") 
    ) 

    select1 = SelectField('Select 1', ...) 
    select2 = SelectField('Select 2', ...) 
    select3 = SelectField('Select 3', ...) 

    def validate(self): 
     data = { 
      "select1": self.select1.data, 
      "select2": self.select2.data, 
      "select3": self.select3.data, 
     } 

     # you can catch the RequirementError 
     # and append the error message to 
     # the form errors 

     self.VALIDATION.validate(data) 
     return result 

您可以验证对象,并添加更多的验证规则,甚至把它放在不同的地方单独的模块和导入/重用验证规则。