2014-02-16 53 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 

您可以驗證對象,並添加更多的驗證規則,甚至把它放在不同的地方單獨的模塊和導入/重用驗證規則。