06-蓝图实战(图书数据搜索与查询),编写get和post请求,同时应用WTForms参数验证

需求:之前的路由请求格式,不是通用的请求格式,转化为get 和 post请求之后,可以通过request方法获取其中的参数

参考格式 04-使用 Flask 框架实现 POST和GET接口 - 马铃薯1 - 博客园 (cnblogs.com)

@web.route('/book/search/<q>')
def search(q):
    pass

 

第三方插件库,WTForms

在flask内部并没有提供全面的表单验证,所以当我们不借助第三方插件来处理时候代码会显得混乱,而官方推荐的一个表单验证插件就是wtforms。

wtfroms是一个支持多种web框架的form组件,主要用于对用户请求数据的进行验证,其的验证流程与django中的form表单验证由些许类似,本文主要介绍wtforms组件使用方法以及验证流程。

wtforms依照功能主要分为以下几个类别:
  • Forms: 主要用于表单验证、字段定义、HTML生成,并把各种验证流程聚集在一起进行验证。
  • Fields: 主要负责渲染(生成HTML)和数据转换。
  • Validator:主要用于验证用户输入的数据的合法性。比如Length验证器可以用于验证输入数据的长度。
  • Widgets:html插件,允许使用者在字段中通过该字典自定义html小部件。
  • Meta:用于使用者自定义wtforms功能,例如csrf功能开启。
  • Extensions:丰富的扩展库,可以与其他框架结合使用,例如django。

注意:

WTForms 表单类 searchForm 期待的输入是一个支持 getlist 方法的 MultiDict 类型

1) get请求获取的 request.args 是MultiDict 类型

2) post请求获取的 request.get_json() 是普通dict 类型,因此需要转换为 MultiDict(request.get_json()) 类型

 
pip安装
pip install wtforms

 

蓝图实战(图书数据搜索与查询)

项目结构

 配置文件 config.py

# 配置参数
DEBUG = True

入口文件 fisher2.py

复制代码
from flask import Flask, make_response, jsonify
from datetime import datetime

from app import create_app

# 创建flask对象
app = create_app()


if __name__ == '__main__':

    app.run(host= '0.0.0.0', debug=app.config['DEBUG'], port=5000)
复制代码

视图函数,校验文件 app/form/book.py

复制代码
# 使用WTForms验证用户输入参数的有效性

from wtforms import Form, StringField, validators

class searchForm(Form):
    # 校验规则,参数不能为空、验证用户输入的字符串长度在1到30之间、
    q = StringField(validators=[
        validators.DataRequired(message="参数不能为空"),
        validators.Length(min=1, max=30)])
复制代码

 

1) 创建蓝图

初始化 app/web/__init__.py

# 蓝图 blueprint 蓝本
from flask import Blueprint

web = Blueprint('web', __name__)

from app.web import book

指定路由和视图函数 app/web/book.py

复制代码
from flask import jsonify, Blueprint, request
from multidict import MultiDict

from httpTest import HTTP
from . import web
from ..forms.book import searchForm

# # 蓝图 blueprint 蓝本
# web = Blueprint('web', __name__)

# 关键字搜索:http://t.talelin.com/v2/book/search?q={}&start={}&count={}
# isbn搜索: http://t.talelin.com/v2/book/isbn/{isbn}
ISBN_URL = "http://t.talelin.com/v2/book/isbn/{}"
KEY_URL = "http://t.talelin.com/v2/book/search?q={}&start={}&count={}"

# get请求
@web.route('/book/getSearch/', methods=['GET'])
def getSearch():
    print("========正在获取get请求=========")

    # # 从请求参数中获取 q
    # q = request.args.get('q')
    # print("参数q:", q)

    # 校验
    form = searchForm(request.args)
    if form.validate():
        # 从请求参数中获取 q (从form中取数,能够更好的验证)
        q = form.q.data
        # strip() 方法用于移除字符串头尾的空白字符或指定字符序列
        q = q.strip()

        # 调用search_book_data方法,获取图书数据
        result = search_book_data(q)

        return jsonify(result), 200
    else:
        return jsonify(form.errors), 400


# post请求
@web.route('/book/postSearch/', methods=['POST'])
def postSearch():
    print("========正在获取post请求=========")

    # # 从请求参数中获取 q
    # # 首先获取 JSON 请求体
    # data = request.get_json()
    # # 然后再从请求体中提取参数
    # q = data.get('q')
    # print("参数q:", q)

    # 校验
    # 首先获取 JSON 请求体
    data = request.get_json()
    # 将 JSON 字典转换为 MultiDict
    form_data = MultiDict(data)
    form = searchForm(form_data)
    if form.validate():
        # 从请求参数中获取 q (从form中取数,能够更好的验证)
        q = form.q.data
        # strip() 方法用于移除字符串头尾的空白字符或指定字符序列
        q = q.strip()

        # 调用search_book_data方法,获取图书数据
        result = search_book_data(q)

        return jsonify(result), 200
    else:
        return jsonify(form.errors), 400

def search_book_data(q):
    # 调用is_isbn_or_key方法,判断q是关键字还是isbn
    isbn_or_key = is_isbn_or_key(q)

    # 根据isbn_or_key的值,获取相应的url
    if isbn_or_key == "isbn":
        url = ISBN_URL.format(q)
        print("进入isbn查询,url:", url)
        result = HTTP.get(url)
    else:
        url = KEY_URL.format(q, 1, 5)
        print("进入关键字查询,url:", url)
        result = HTTP.get(url)

    return result


def is_isbn_or_key(q):
    # 默认q为关键字
    isbn_or_key = "key"

    # 判断q是否为isbn
    # isbn13 是由13位0到9数字组成的字符串
    # isbn10 是由10位0到9数字组成,含有一些 "-"
    if q.isdigit() and len(q) == 13:
        isbn_or_key = "isbn"

    short_q = q.replace("-", "")
    if q.isdigit() and len(short_q) == 10 and q in "-":
        isbn_or_key = "isbn"

    return isbn_or_key
复制代码

视图函数文件 httpTest.py

复制代码
import requests

class HTTP:
    # 发送GET请求
    @staticmethod
    def get(url, return_json=True):
        response = requests.get(url)
        if response.status_code == 200:
            if return_json:
                return response.json()
            else:
                return response.text
        else:
            print(f"Error: {response.status_code}")
            return None

    # 发送POST请求
    @staticmethod
    def post(url, data, headers={}, return_json=True):
        response = requests.post(url, data=data, headers=headers)
        if response.status_code == 200:
            if return_json:
                return response.json()
            else:
                return response.text
        else:
            print(f"Error: {response.status_code}")
            return None
复制代码

 

2) 注册蓝图,在初始化中实例化flask对象,并注册蓝图

初始化 app/__init__.py

复制代码
from flask import Flask
from app.web import web

def create_app():
    # 实例化flask对象
    app = Flask(__name__)
    # flask对象加载配置文件
    app.config.from_object('config')

    # 调用注册蓝图的方法
    register_blueprint(app)
    return app

def register_blueprint(app):
    # 注册蓝图
    app.register_blueprint(web)
复制代码

 

get请求测试

 

post请求测试

 

 

 

posted @   马铃薯1  阅读(40)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示