2012-06-29 76 views
2

我看到很多應用程序使用Form對象來驗證數據,然後將數據傳遞給模型,同時在模型中完全不驗證。我覺得最好將模型本身的核心驗證(例如,沒有18歲以下的用戶)放在不管上下文的情況下運行。換句話說,我不在乎用戶是如何創建的(無論是通過web ui還是命令行),核心規則應該始終適用。我想使用SQLAlchemy(在金字塔應用程序中),我想以我的表單(WTForms)始終尊重模型中定義的核心規則的方式在模型中定義我的核心驗證規則,以便所有數據是一致的。如何使用SQLAlchemy在模型中進行表單驗證?

其他人已經在做這個或類似的東西嗎?

this php類似的解決方案。

+0

難道你不能重寫你在模型類中使用你的模型的get/put/save/create方法嗎(因爲它們應該總是優先),那麼就用'super'來做實際的創建/更新如果它通過測試? –

+1

爲什麼不在模型中進行驗證的原因之一是您可能有不同的形式。一個有趣的例子是保存一個不完整的模型。如果您嘗試保存不完整的模型,那麼您的模型驗證將失敗,但是如果您在表單中進行了驗證。一種形式可能會失敗或通過,但最終結果總是有效的。在模型中進行驗證會使您執行一些醜陋的事情,例如條件驗證......請記住,模型不應該包含任何邏輯。 –

+0

@LoïcFaure-Lacroix非常好的一點,但我只考慮核心規則,這可以防止保存不完整/損壞的模型。例如,「數據庫中的每個用戶必須具有有效年齡,沒有例外」。我覺得像這樣重要的規則應該存在於模型中,如果你願意的話,它可以作爲最後的防禦牆。 – BDuelz

回答

2

SQLAlchemy允許您註冊偵聽器,當發生某些事件時會調用這些偵聽器,例如,您可以註冊在模型字段被修改時要觸發的事件。從SQLAlchemy documentation

聽衆必須返回 值的可能修改的版本的選項,當RETVAL = True標誌被傳遞給聽():

def validate_phone(target, value, oldvalue, initiator): 
    "Strip non-numeric characters from a phone number" 

    return re.sub(r'(?![0-9])', '', value) 

# setup listener on UserContact.phone attribute, instructing 
# it to use the return value 
listen(UserContact.phone, 'set', validate_phone, retval=True) 

甲驗證函數像上述也可以提起例外 作爲ValueError停止操作。

因此,如您所見,您可以在模型級別修改或拒絕特定字段的值。

我不確定您的表單庫是否與此功能集成,但它絕對不應該太難以推出您自己的解決方案。

+2

[@validates](http://docs.sqlalchemy.org/en/rel_0_9/orm/mapper_config.html#simple-validators)呢? – Zitrax

+0

@Zitrak:鏈接已更改,它現在是http://docs.sqlalchemy.org/en/rel_0_9/orm/mapped_attributes.html#simple-validators – runejuhl