<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python Web領(lǐng)域中,參數(shù)校驗(yàn)?zāi)募覐?qiáng)?

          共 4723字,需瀏覽 10分鐘

           ·

          2021-09-27 09:45

          用Python做Web后端開發(fā)的同學(xué)想必都知道,如何快速解析和校驗(yàn)前端傳遞過來的請(qǐng)求參數(shù)是代碼中必不可少的任務(wù)。

          以flask為例

          @app.route("/api/login", methods=["POST"])
          def login():
              data = request.get_json()
              # 郵箱格式校驗(yàn)
              email = data.get("email")
              if not email or re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", email):
                  return jsonify({"code"400"msg""參數(shù)有誤"}), 400
              # 密碼長(zhǎng)度校驗(yàn)
              password = data.get("password")
              if not password or len(password) < 6:
                  return jsonify({"code"400"msg""參數(shù)有誤"}), 400
              # 數(shù)據(jù)庫(kù)查詢
              return jsonify({"code"200"msg""ok"})

          對(duì)于一個(gè)簡(jiǎn)單的登錄接口,要寫一堆又臭又長(zhǎng)的參數(shù)校驗(yàn)邏輯,而這些本是和業(yè)務(wù)邏輯沒什么關(guān)系的代碼。

          只要是和業(yè)務(wù)無關(guān)的代碼,我們總能找到一些框架或者庫(kù)來解決問題,而針對(duì)web請(qǐng)求參數(shù)的解析和校驗(yàn)庫(kù), webargs 就是一款強(qiáng)大的工具。它直接站在巨人的肩膀上,基于marshmallow做了字段規(guī)則校驗(yàn)工作,如果熟悉 marshmallow 的同學(xué)上手這個(gè)庫(kù)也就半小時(shí)。

          另一個(gè)特點(diǎn)是它針對(duì)市面上常見的web框架都寫了一個(gè)單獨(dú)的解析器parser,對(duì)開發(fā)者來說無疑是真香,不管你用的是哪個(gè)web框架,都能無縫接入webargs到項(xiàng)目中,無需我們自己做過多封裝。

          安裝

          $ pip install -U webargs

          使用

          from webargs import fields
          from webargs.flaskparser import use_args

          app = Flask("hello")


          @app.route("/api/login", methods=["POST"])
          @use_args({"username": fields.Str(required=True),
                     "password": fields.Str(required=True, validate=lambda x: len(x) >= 6)})
          def login(args):
              name = args['username']
              password = args['password']
              return jsonify({"code"200"msg""ok"})

          use_args 是 webargs 提供的裝飾器,正是有了這個(gè)裝飾器,它能處理前端傳過來的請(qǐng)求參數(shù),我們只要定義好schema,剩下的交給webargs。

           所謂 schema 就是你希望前端傳過來的參數(shù)有哪些,每個(gè)參數(shù)的類型是什么,應(yīng)該滿足什么規(guī)則等等。

          這里我們定義的schema要求usename字段必須是字符串,而且是必填項(xiàng), password 的長(zhǎng)度必須大于6.

          如果你用的是django,只需要導(dǎo)入djangoparser下的use_args 即可

          from webargs.djangoparser import use_args

          如果用戶沒有按照要求發(fā)送數(shù)據(jù),代碼壓根就不會(huì)執(zhí)行到我們的業(yè)務(wù)代碼中去,直接在裝飾器就把錯(cuò)誤返回給上層了,所以代碼整潔了不少。

          如果傳的參數(shù)不符合要求,默認(rèn)返回的錯(cuò)誤碼是422。但是返回的錯(cuò)誤信息似乎看不懂,api的調(diào)用者看了并不知道參數(shù)錯(cuò)在哪里。

          我們可以專門針對(duì)錯(cuò)誤重新處理一下,同樣返回一個(gè)格式可讀的json體給前端, 這是flask的特性,如果是django,請(qǐng)自行查找相應(yīng)的方法

          @app.errorhandler(422)
          @app.errorhandler(400)
          def handle_error(err):
              headers = err.data.get("headers"None)
              messages = err.data.get("messages", ["Invalid request."])
              if headers:
                  return jsonify({"errors": messages}), err.code, headers
              else:
                  return jsonify({"errors": messages}), 400

          location

          webargs 默認(rèn)情況下是從請(qǐng)求body中以json格式來讀取和解析參數(shù)的,如果要通過其他方式獲取,就需要指定在use_args中指定location

          @app.route("/", methods=["GET"])
          @use_args({"name": fields.Str(missing="Friend")}, location="querystring")
          def index(args):
              """A welcome page."""
              return jsonify({"message""Welcome, {}!".format(args["name"])})


          location可支持的類型有:

          • 'querystring':通過url后面的查詢參數(shù)獲取
          • 'json'  # 把請(qǐng)求body當(dāng)作json來獲取參數(shù)
          • 'form'  # 通過form表單獲取參數(shù)
          • 'headers'  # 通過請(qǐng)求頭獲取參數(shù)
          • 'cookies'   # 通過cookie獲取
          • 'files'  # 通過文件獲取

          驗(yàn)證器

          webargs 最強(qiáng)大的地方其實(shí)還在Field提供的校驗(yàn)規(guī)則,依賴于marshmallow,我們可以指定每個(gè)字段的數(shù)據(jù)類型,支持的類型非常多。大部分都是marshmallow提供了,webargs自己也提供了部分字段類型。


          除了可以指定具體的類型外,我們還可以指定驗(yàn)證器來要求字段符合某種規(guī)則, validate 接收的參數(shù)是函數(shù),意味著我們可以自定義任何規(guī)則。

          def must_exist_in_db(val):
              if val != 1:
                  raise ValidationError("id not exist")


          hello_args = {"name": fields.Str(missing="Friend"),
                        "id": fields.Integer(required=True, validate=must_exist_in_db)}


          @app.route("/", methods=["GET"])
          @use_args(hello_args, location="query")
          def hello(args):
              """A welcome page."""
              return jsonify({"message""Welcome, {}!".format(args["name"])})

          先介紹這么多,更多高級(jí)功能參考:https://webargs.readthedocs.io/en/latest/quickstart.html

            趕緊在你的項(xiàng)目中試試吧!


           

          - EOF -

            推薦閱讀:


          點(diǎn)擊關(guān)注【python之禪】,提升Python技能
          ??????


          好文章需要您的點(diǎn)贊加在看~

          瀏覽 124
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产亚洲网 | 九九福利视频 | 黄色免费网站在线看 | 女警高潮一级毛毛片 | 婷婷九月av在线观看 |