Python Flask学习知识点(四)

简介: timg (8).jpg上节讲到,视图函数可以以接受参数的形式来获取传入后台的参数,但是往往我们需要对参数进行校验,比如说请求一个10条数据,那么page=10,但是如果某些比较皮的小盆友传入一个page=10000,那服务器也要去数据库查询10000条记录返回吗?显然不能那么做,所以这就涉及到在Flask中做参数检查的工作。
img_9abb1c7455e254f0489be17cb3aa1f44.jpe
timg (8).jpg

上节讲到,视图函数可以以接受参数的形式来获取传入后台的参数,但是往往我们需要对参数进行校验,比如说请求一个10条数据,那么page=10,但是如果某些比较皮的小盆友传入一个page=10000,那服务器也要去数据库查询10000条记录返回吗?显然不能那么做,所以这就涉及到在Flask中做参数检查的工作。

WTForms参数验证

首先,安装这个第三方的插件wtforms
pip install wtforms
我们都知道,在web应用中,分层这个概念非常重要,MVC模式其实可以理解为就是分层,这里我们引入验证层这个概念。无论写任何的web应用,验证层都是非常重要的概念。

所以我们所有的参数校验工作,都不会直接写到视图函数中,而是都会放到验证层去做。
在app文件夹下新建forms文件夹,并新建book.py文件:


img_8bcae5f883e40e45b7f018628bafcc15.png
image.png

编写book.py:

from wtforms.validators import Length, NumberRange, DataRequired()

from wtforms import Form, StringField, IntegerField

class SearchForm(Form):
    q = StringField(validators=[DataRequired(), Length(min=1, max=30)])
    page = IntegerField(validators=[NumberRange(min=1, max=99)], default=1)

解释这段代码:
使用wtforms提供的StringField对象来定义参数q的类变量
使用wtforms提供的IntegerField对象来定义参数page的类变量

wtforms内置了很多的验证对象来帮助我们快速的完成对参数的验证,而不需要手动编写验证函数。当然了,我们也可以自定义验证对象。
为了验证q参数,可以使用内置的验证对象:Length,验证q参数的长度,validators接受一个list,可以传入多个验证对象,这里我们验证q参数传入Length验证对象。
同样,验证page参数也是同样的原理,这里使用的三个内置的验证对象(NumberRange,Length,DataRequired),可以查阅文档了解详细的用法。
编写完验证层代码,在视图函数中调用,更改web文件夹下book.py:

from flask import jsonify, request

from flaskDemo.app.forms.book import SearchForm
from . import web

@web.route('/hello')
def search():
    form = SearchForm(request.args)
    if form.validate():
        q = form.q.data
        page = form.page.data
        result = {"name": q, "valus": page}
        return jsonify(result)
    return jsonify({"error": 0})

解释代码:
首先导入SearchForm并实例化为form对象,并且传入参数request.args,通过form.validate()的返回值判断是否符合验证器规定的结果。
这里讲一点,使用page = form.q.data这种方式获取q和page的值,而不直接使用q,是因为我们之前在验证层SearchForm中定义了page参数如果为空,使用1为默认值,所以我们要从form.q.data 这种拿到page参数。

看下效果,运行run.py启动,在浏览器中输入符合规则的urlhttp://127.0.0.1:8000/hello?q=demo&page=1
再输入不符合规则的urlhttp://127.0.0.1:8000/hello?q=demo&page=100
返回结果:

img_9e19f9c6f3d15a314c711938d51728aa.png
image.png

img_bc3906ed1b2e354fc34664eb28a9b235.png
image.png

一个是成功,一个是失败。
因为之前我们在验证层中定义了page的最大值为99,所以如果输入100,就会返回错误。
再试一下不输入page参数:http://127.0.0.1:8000/hello?q=demo

img_8f1abd2bf28cd7dbe525ed37781adb51.png
image.png

还是可以返回默认值。

继续,看下图:


img_36fe6fa22e703d3cc7baf984b16faa06.png
image.png

debug调试过程中,看下form实例中的一个errors,这个errors就是当验证不通过时,wtforms给我们的一个错误提示,在一般情况下,如果参数验证不通过时是会抛出一个异常的,但是使用wtforms,它会把错误提示放到errors属性中而不抛出异常。
更改代码:

def search():
    form = SearchForm(request.args)
    if form.validate():
        q = form.q.data
        page = form.page.data
        result = {"name": q, "valus": page}
        return jsonify(result)
    return jsonify({"error": form.errors})

这里改为return jsonify({"error": form.errors})

再运行代码输入URLhttp://127.0.0.1:8000/hello?q=demo&page=100得到如下:

img_b6ce731c29967c318dff7317184b160b.png
image.png

可见wtforms告诉我们为什么验证不通过。

这里也可以在SearchForm自定义返回的错误信息,只需更改为:

class SearchForm(Form):
    q = StringField(validators=[DataRequired(), Length(min=1, max=30)])
    page = IntegerField(validators=[NumberRange(min=1, max=99, message="传入的参数不符合要求")], default=1)

再运行代码:


img_7a32f9c772d37cec842df39d988a7a84.png
image.png

拆分配置文件

之前我们一直是把配置参数全部放到config.py中,但是这样的话会有一个问题,那就是如果我们把比较私密的配置(例如数据库地址以及密码)和普通的参数放在一起,势必会有安全风险,比如把代码传到了git上,所以最好把配置文件拆分为两种不同级别的,这里我们把config.py拆分为secure.py和setting.py,并且全部放到app文件夹下。

secure.py 用来存放数据库密码、账号还有我们后边提到的flask app key ,这样比较机密的信息,单独放配置文件中,还有就是开发环境和生产环境中的不同设置,比如 debug=True。
setting.py 用来存放不涉及到机密的,生产和开发环境一样的配置。

更改之前的代码,app文件夹下的__init__.py:

def create_app():
    app = Flask(__name__)
    app.config.from_object("app.setting")
    app.config.from_object("app.secure")

    register_blueprint(app)
    return app

current_app

在Flask中,如果要在运行中读取配置文件中的参数,需要使用Flask核心对象app来查找,但是之前讲过,如果反复导入app,或造成循环导入,那么解决方法就是使用current_app,current_app其实就是指代的app,
例如,读取配置文件中的PER_PAGE变量:

因为之前我们做了这个操作:

def create_app():
    app = Flask(__name__)
    app.config.from_object("app.setting")
    app.config.from_object("app.secure")

    register_blueprint(app)
    return app

把setting.py和secure.py中的配置加到了Flask内置config对象中,所以要这样读取配置文件中的变量:

current_app.config['PER_PAGE']

欲知后事如何,请看下回分解,记得点个赞~感谢

目录
相关文章
|
3天前
|
小程序 程序员 开发者
Python学习心得——小白的成长之路
Python学习心得——小白的成长之路
11 0
|
4天前
|
网络安全 Python
网安之python基础学习练习(2-3)
本篇博文是关于网络安全课程中Python编程的学习实践总结。分享关于两个练习题目及其解决方案。第一个题目要求用户输入姓名并选择一项武技,使用for循环和if判断实现。第二个题目是删除列表中特定值(如'cat')的所有元素,作者展示了两种方法,包括列表推导式和常规循环删除。接下来,文章还介绍了如何编写一个函数,随机生成一副扑克牌(除大小王),并返回一张随机抽取的牌。
|
4天前
|
存储 网络安全 索引
网安之python基础学习练习(1)
本篇博文是关于网络安全课程中Python编程学习的总结,主要内容包括:1) 常见数据类型的回顾和应用,如数字(整数、浮点数、复数)、字符串、列表、元组、集合、字典和布尔类型;2) 数据类型的实例操作,展示如何创建和使用这些类型;3) 数值类型之间的加、减、乘、除和模运算;4) 列表和元组的索引访问;5) 字典的修改,如查看键和值,以及更新值。文章强调了基础知识的重要性,并以“自满必定失败,骄傲必定后悔”作为每日一言。
|
6天前
|
机器学习/深度学习 数据挖掘 程序员
Python学习难度的具体标准
Python学习难度因个人编程背景、目标、资源和学习能力而异。对有编程经验者来说,Python的简单语法使其易上手;而对于新手,理解基础概念可能需更多时间。不同应用领域(如Web开发、数据分析)的学习曲线也不同。丰富的学习资源适应各种水平,但选择合适资源很重要。成功学习Python需要逻辑思维、问题解决能力及毅力。总的来说,Python学习难度因人而异,需结合自身条件评估。
19 0
|
6天前
|
存储 索引 Python
python数据结构知识学习
【5月更文挑战第6天】Python提供四种核心数据结构:列表(List)——可变有序集合,支持索引和切片;元组(Tuple)——不可变有序集合;字典(Dictionary)——键值对结构,通过键访问值;集合(Set)——无序不重复元素集合,支持数学运算。此外,Python允许自定义数据结构,如链表、树、图,以适应不同问题需求。
15 0
|
11天前
|
机器学习/深度学习 分布式计算 物联网
【Python机器学习专栏】联邦学习:保护隐私的机器学习新趋势
【4月更文挑战第30天】联邦学习是保障数据隐私的分布式机器学习方法,允许设备在本地训练数据并仅共享模型,保护用户隐私。其优势包括数据隐私、分布式计算和模型泛化。应用于医疗、金融和物联网等领域,未来将发展更高效的数据隐私保护、提升可解释性和可靠性的,并与其他技术融合,为机器学习带来新机遇。
|
11天前
|
机器学习/深度学习 自然语言处理 搜索推荐
【Python机器学习专栏】迁移学习在机器学习中的应用
【4月更文挑战第30天】迁移学习是利用已有知识解决新问题的机器学习方法,尤其在数据稀缺或资源有限时展现优势。本文介绍了迁移学习的基本概念,包括源域和目标域,并探讨了其在图像识别、自然语言处理和推荐系统的应用。在Python中,可使用Keras或TensorFlow实现迁移学习,如示例所示,通过预训练的VGG16模型进行图像识别。迁移学习提高了学习效率和性能,随着技术发展,其应用前景广阔。
|
11天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习中的Bagging与Boosting
【4月更文挑战第30天】本文介绍了集成学习中的两种主要策略:Bagging和Boosting。Bagging通过自助采样构建多个基学习器并以投票或平均法集成,降低模型方差,增强稳定性。在Python中可使用`BaggingClassifier`实现。而Boosting是串行学习,不断调整基学习器权重以优化拟合,适合弱学习器。Python中可利用`AdaBoostClassifier`等实现。示例代码展示了如何在实践中运用这两种方法。
|
11天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习专栏】关联规则学习:Apriori算法详解
【4月更文挑战第30天】Apriori算法是一种用于关联规则学习的经典算法,尤其适用于购物篮分析,以发现商品间的购买关联。该算法基于支持度和置信度指标,通过迭代生成频繁项集并提取满足阈值的规则。Python中可借助mlxtend库实现Apriori,例如处理购物篮数据,设置支持度和置信度阈值,找出相关规则。
|
11天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习算法的原理与应用
【4月更文挑战第30天】集成学习通过组合多个基学习器提升预测准确性,广泛应用于分类、回归等问题。主要步骤包括生成基学习器、训练和结合预测结果。算法类型有Bagging(如随机森林)、Boosting(如AdaBoost)和Stacking。Python中可使用scikit-learn实现,如示例代码展示的随机森林分类。集成学习能降低模型方差,缓解过拟合,提高预测性能。