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']

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

目录
相关文章
|
5天前
|
API 数据库 数据安全/隐私保护
Flask框架在Python面试中的应用与实战
【4月更文挑战第18天】Django REST framework (DRF) 是用于构建Web API的强力工具,尤其适合Django应用。本文深入讨论DRF面试常见问题,包括视图、序列化、路由、权限控制、分页过滤排序及错误处理。同时,强调了易错点如序列化器验证、权限认证配置、API版本管理、性能优化和响应格式统一,并提供实战代码示例。了解这些知识点有助于在Python面试中展现优秀的Web服务开发能力。
22 1
|
2天前
|
运维 Shell Python
Shell和Python学习教程总结
Shell和Python学习教程总结
|
2天前
|
Python
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
|
2天前
|
开发框架 前端开发 数据库
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
|
2天前
|
数据采集 数据可视化 数据处理
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
|
2天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
5天前
|
SQL 中间件 API
Flask框架在Python面试中的应用与实战
【4月更文挑战第18天】**Flask是Python的轻量级Web框架,以其简洁API和强大扩展性受欢迎。本文深入探讨了面试中关于Flask的常见问题,包括路由、Jinja2模板、数据库操作、中间件和错误处理。同时,提到了易错点,如路由冲突、模板安全、SQL注入,以及请求上下文管理。通过实例代码展示了如何创建和管理数据库、使用表单以及处理请求。掌握这些知识将有助于在面试中展现Flask技能。**
12 1
Flask框架在Python面试中的应用与实战
|
6天前
|
数据可视化 Python
Python模型评估与选择:面试必备知识点
【4月更文挑战第17天】本文深入探讨了Python模型评估与选择在面试中的关键点,包括性能度量、过拟合与欠拟合识别、模型比较与选择、模型融合和偏差-方差权衡。强调了避免混淆评估指标、忽视模型验证和盲目追求高复杂度模型的常见错误,并提供相关代码示例,如交叉验证、网格搜索和超参数调优。通过理解这些概念和技巧,可在面试中展示出色的数据科学能力。
31 12
|
7天前
|
数据安全/隐私保护 Python
Python Flask-Mail实现邮件发送
Python Flask-Mail实现邮件发送
|
9天前
|
机器学习/深度学习 算法 Python
使用Python实现集成学习算法:Bagging与Boosting
使用Python实现集成学习算法:Bagging与Boosting
19 0