<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ## 第5章 理解WTForms并靈活改造她 WTForms其實是非常強大的驗證插件。但很多同學對WTForms的理解僅僅停留在“驗證表單”上。那WTForms可以用來做API的參數驗證碼?完全可以,但這需要你靈活的使用它,對它做出一些“改變” ### 5-1 重寫WTForms 一 原因: * 之前做的表單驗證只是將所有驗證錯誤歸結于客戶端類型錯誤,并沒有具體分到底是客戶端傳入的哪個數據有問題 * 代碼寫起來繁瑣,我們需要在每一個需要做表單驗證的視圖函數內寫 else 來拋出異常 ### 5-2 重寫WTForms 二 其實我們在執行 form.validate 的時候內部已經產生了一個異常,只是異常沒有拋出來而已,所以我們只需要 wtforms 在執行 form.validate 之后將異常拋出來就可以了。 #### 在 BaseForm 中覆寫 Form 首先新建 ginger/app/validators/base.py ~~~ ?from wtforms import Form ?? ?from app.libs.error_code import ParameterException ?? ?? ?class BaseForm(Form): ? ? ?def __init__(self, data): ? ? ? ? ?super(BaseForm, self).__init__(data=data) ?? ? ? ?def validate_for_api(self): ? ? ? ? ?valid = super(BaseForm, self).validate() ? ? ? ? ?if not valid: ? ? ? ? ? ? ?raise ParameterException(self.errors) ~~~ 1. 因為 BaseForm 需要接收客戶端傳過來的數據,所以在構造函數的參數里傳入 data 2. 在構造函數內調用父類(wtforms 的 Form)的構造函數進行初始化 3. 我們可以覆寫父類的 validate 方法也可以為 api 表單驗證寫一個單獨的 validate\_for\_api 方法 * 在 validate\_for\_api 內調用父類的 validate 方法,就會讓 validate\_for\_api 具備與 validate 相同的功能 * 父類 validate 方法執行過程中產生的異常都保存在 forms.errors 屬性中 * 其次用 valid 接收父類 validate 的返回結果,將結果中的異常拋出 這樣 BaseForm 就具備了拋出異常的能力。 #### 繼承 BaseForm 將 ginger/app/validator/forms.py 內的所有表單都繼承 BaseForm。 ~~~ ?from app.validators.base import BaseForm as Form ~~~ 直接在視圖函數內調用 validate\_for\_api 就可以在表單驗證遇到異常的時候終止程序并拋出異常信息。 ~~~ ?@api.route('/register', methods=['POST']) ?def create_client(): ? ? ?form = ClientForm(data=request.json) ? ? ?form.validate_for_api() ? ? ?promise = { ? ? ? ? ?ClientTypeEnum.USER_EMAIL: __register_by_email, ? ? ? ? ?ClientTypeEnum.USER_MOBILE: __register_by_mobile, ? ? ? ? ?ClientTypeEnum.USER_MINA: __register_by_mina, ? ? ? ? ?ClientTypeEnum.USER_WX: __register_by_wx, ? ? } ? ? ?promise[form.type.data]() ? ? ?return 'register client success' ~~~ ### 5-3 可以接受定義的復雜,但不能接受調用的復雜 1. 優化 data=request.json 將 data=request.json 寫入到 BaseForm 中,以后調用就不需要手動傳入 ~~~ ?class BaseForm(Form): ? ? ?def __init__(self): ? ? ? ? ?data = request.json ? ? ? ? ?super(BaseForm, self).__init__(data=data) ~~~ 2. 第一步優化好之后,視圖函數中的代碼如下 ~~~ ?form = ClientForm() ?form.validate_for_api() ~~~ 這里還能不能優化呢?顯然是可以的,可以寫成 ~~~ ?form = ClientForm().validate_for_api() ~~~ 但是 validate\_for\_api 內部并沒有返回 form,所以左邊的 form 賦值就會報錯,怎么辦?強制讓 validate\_for\_api 返回 form!因為 validate\_for\_api 是寫在 BaseForm 內的,此時的 self 就是 form。 ~~~ ? ? ?def validate_for_api(self): ? ? ? ? ?valid = super(BaseForm, self).validate() ? ? ? ? ?if not valid: ? ? ? ? ? ? ?raise ParameterException(self.errors) ? ? ? ? ?return self ~~~ ### 5-4 已知異常與未知異常 到目前為止客戶端傳給服務器的都是 JSON 格式的數據,如果不是 JSON 格式的數據呢? ![](https://ws3.sinaimg.cn/large/006tNbRwgy1fyr9tjdz3sj32f30u0n3e.jpg) 異常可以分為: * 已知異常 * 未知異常 ### 5-5 全局異常處理 如何捕捉未知異常呢?這就需要用到 AOP 的思想。不管異常產生在哪里,我只需要在全局捕捉異常并處理就可以解決問題了。 在項目的啟動文件內寫全局捕捉錯誤的函數。分類判斷該錯誤是 APIException、HTTPException 還是最基本的 Exception,對應的編寫處理方法。 ~~~ ?from werkzeug.exceptions import HTTPException ?? ?from app.app import create_app ?from app.libs.error import APIException ?from app.libs.error_code import ServerError ?? ?app = create_app() ?? ?? ?@app.errorhandler(Exception) ?def framework_error(e): ? ? ?if isinstance(e, APIException): ? ? ? ? ?return e ? ? ?if isinstance(e, HTTPException): ? ? ? ? ?code = e.code ? ? ? ? ?msg = e.description ? ? ? ? ?error_code = 1007 ? ? ? ? ?return APIException(msg, code, error_code) ? ? ?else: ? ? ? ? ?if app.config['DEBUG']: ? ? ? ? ? ? ?raise e ? ? ? ? ?else: ? ? ? ? ? ? ?return ServerError() ?? ?? ?if __name__ == '__main__': ? ? ?app.run(debug=True) ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看