第二篇 Flask基础篇之(闪现,蓝图,请求扩展,中间件)

本篇主要内容:

  闪现

  请求扩展  

  中间件  

  蓝图

写装饰器,常用 functools模块,帮助设置函数的元信息

import functools

def wrapper(func):
    @functools.wraps(func)
    def inner(*args,**kwargs):
        return func(*args,**kwargs)

    return inner

@wrapper
def f1():
    pass

print(f1.__name__)  # f1

续接第一篇

8.Flask之闪现

# 首先要导入flash 和 get_flashed_messages
from flask import Flask,flash,get_flashed_messages
app = Flask(__name__)
app.secret_key="1234"

@app.route("/get")
def get():
    # 2.从某个地方获取设置过的所有值,并清除。 类似于pop
    # 第一次运行可以获取到所有的设置的值;第二次运行就清除掉了所有的设置的值
    data = get_flashed_messages()
    print(data)
    return "hello World"

@app.route("/set")
def set():
    # 1. 向某个地方设置一个值
    flash("军人")
    return "Hello army"

if __name__=="__main__":
    app.run()

闪现有什么作用呢?

比如:假设在A页面做个操作,但该操作失败了,要跳转到B页面并显示这些错误信息
from flask import Flask,flash,get_flashed_messages,request,redirect
app = Flask(__name__)
app.debug = True
app.secret_key="1234"

@app.route("/index")
def index():
    # get请求用request.args.get, v是接受参数的变量
    # 浏览器请求:
    val = request.args.get(‘v‘)
    if val =="body":
        return "hello World, guys"
    # 如果请求参数不是body,则跳转到错误页面,需要将错误信息flash,也就是设置错误值到某个地方
    # A.flash不分类,直接设置值
    flash("前端输入参数错误")
    # B.flash还可以对错误信息,进行分类
    flash("前端输入参数错误", category="x1")
    return redirect("/error")

@app.route("/error")
def error():
    ‘‘‘
    显示错误信息
    ‘‘‘
    # 跳转到error页面后,请求时获取错误信息
    # A.flash没有分类时
    # data = get_flashed_messages()   # 获取的就是flash的值
    # B. 对于有分类的,取值时可以通过 category_filter 根据分类取错误信息
    data = get_flashed_messages(category_filter=[‘x1‘])
    # 可能有很多的错误信息,也可以按照索引的方式取出错误值
    if data:
        msg = data[0]
    else:
        msg = "..."
    return "错误信息:%s" %(msg)

if __name__=="__main__":
    app.run()

闪现是怎么实现的呢?

其实,它就是通过session做的,先把数据存在session里,数据如果在session里,只要不删,就永远在。

然后,如果值被拿走,就会通过session.pop()的方式给拿走。

所以,就不用担心数据错乱。因为每个用户都会有自己的一个session,基于session就会把数据隔离开了。

闪现的应用:

  对临时数据操作,如:显示错误信息

9.Flask之请求扩展(类似Django中间件)--其实也是Flask的中间件

场景:

商业应用一般都要求登录后才可以进行其他操作,上一篇我们基于装饰器的方式做,但是如果函数越来越多,那就要新增一个函数,就要添加一个装饰器。

为了省事,在Django里通过中间件的方式做的,但是Flask里没有类似的中间件,就需要通过Flask里的请求扩展的方式做。

(1)做用户登录认证 before_request   —常用

示例:基于Flask的请求扩展做一个用户认证功能

from flask import Flask,render_template,request,redirect,session,url_for

app = Flask(__name__)
app.debug = True
app.secret_key = "123#234"

USERS = {
    1:{"name":"老大", "age":19,"gender":"男", "resume":"言语措辞间都能体会到今日头条的谨小慎微,生怕再出现任何问题……."},
    2:{"name":"老二", "age":18,"gender":"女", "resume":"当打开这款APP之后,就会发现这跟已经“死”去的内涵段子简直是一模一样。更厉害的地方是,它还支持用用户迁移内涵段子上的内容信息。"},
    3:{"name":"老三", "age":17,"gender":"男", "resume":"如果狒狒会说人话,他肯定是在说:喂…你怎么只给我吃了一口就跑了呀,我还没吃饱啊…喂喂喂…给我回来呀!哈哈哈"},
}

# 基于flask里请求扩展来做
@app.before_request
def process_request(*args, **kwargs):
    # 验证表示,任何地址请求都会先执行before_request,所以登录验证就可以在before_request里做用户认证功能了
    print("其他请求之前就执行了process_request")
    # 4.访问/login的时候还没有登录,就会一直重定向到登录页,所以就要设置个白名单,如果请求地址是/login,就返回None
    if request.path == "/login":
        return None
    # 1.登录验证功能
    user = session.get(‘user_info‘)
    # 2.如果登录信息正常,什么都不做,程序继续其他执行
    if user:
        return None
    # 3.如果登录验证不通过,就重定向到登录页面
    return redirect("/login")

@app.route("/detail/<int:nid>", methods=[‘GET‘])
def detail(nid):
    detail_info = USERS.get(nid)
    # 如果有值,就跳到详情页
    return render_template("detail.html",info = detail_info)

@app.route("/index", methods=[‘GET‘])
def index():
    return render_template("index.html", user_dict=USERS)

@app.route("/login", methods=[‘GET‘, ‘POST‘], endpoint=‘l1‘)
def login():
    if request.method =="GET":
        return render_template("login.html")
    else:
        user = request.form.get("username")
        pwd = request.form.get("password")
        if user == "alex" and pwd =="123456":
            session[‘user_info‘] = user
            return redirect("/index")
        return render_template("login.html", **{"error":"用户名和密码错误"})

if __name__ == "__main__":
    app.run()

(2)有before_request, 就天然的有after_request —常用

from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = ‘siuljskdjfs‘

@app.before_request
def process_request1(*args,**kwargs):
    print(‘process_request1 进来了‘)

@app.after_request
def process_response1(response):
    print(‘process_response1 走了‘)
    # after_request 必须返回 response
    return response

# 视图函数
@app.route(‘/index‘,methods=[‘GET‘])
def index():
    print(‘index函数‘)
    return "Index"

if __name__ == ‘__main__‘:
    app.run()

(3)请求扩展可以添加多个

from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = ‘siuljskdjfs‘

@app.before_request
def process_request1(*args,**kwargs):
    print(‘process_request1 进来了‘)
    return "拦截"

@app.before_request
def process_request2(*args,**kwargs):
    print(‘process_request2 进来了‘)

@app.after_request
def process_response1(response):
    print(‘process_response1 走了‘)
    # after_request 必须返回 response
    return response

@app.after_request
def process_response2(response):
    print(‘process_response2 走了‘)
    return response

# 视图函数
@app.route(‘/index‘,methods=[‘GET‘])
def index():
    print(‘index函数‘)
    return "Index"

if __name__ == ‘__main__‘:
    app.run()

‘‘‘
Flask请求扩展也可以写多个
但是要注意,多个请求扩展的执行顺序是有差别的:
对于before_request,是按照写的代码的顺序从上到下的顺序正序执行的
对于after_request, 是按照写的代码的顺序从下到上的顺序倒序执行的

如果before_request return了(即程序被拦截了),其他before_request就不执行了,但是所有的after_request都会继续执行
‘‘‘

(4)定制错误信息:errorhandler(404)

from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = ‘siuljskdjfs‘

# 经常会出现url不存在的情况,一般会有错误信息
# 而这个错误信息也是可以进行定制的,根据错误码定制错误信息方法如下:
@app.errorhandler(404)
def error_404(arg):
    return "404错误了"

# 视图函数
@app.route(‘/index‘,methods=[‘GET‘])
def index():
    print(‘index函数‘)
    return "Index"

if __name__ == ‘__main__‘:
    app.run()

(5)模板中定制方法(定制模板方法): template_global()  和  template_filter()

from flask import Flask,request
app = Flask(__name__)
app.debug = True

# 这就是基于请求扩展的 定制模板方法# 相对于在模板里定制了一个函数
@app.template_global()
def sb(a1, a2):
    return a1 + a2

if __name__ == ‘__main__‘:
    app.run()

#在HTML里调用的方式如下:
{{sb(1,2)}}
from flask import Flask,request
app = Flask(__name__)
app.debug = True

# 这就是基于请求扩展的 定制模板方法
@app.template_filter()
def db(a1, a2, a3):
    return a1 + a2 + a3

if __name__ == ‘__main__‘:
    app.run()

#在HTML里调用的方式如下:
 {{ 1|db(2,3)}   # 参数 a1 = 1,是第一个参数; a2=2 是第二个参数;   a3=3 是第三个参数

(6)只有第一次请求才执行的:before_first_request

  比如:数据库的连接,初始化操作

from flask import Flask,request
app = Flask(__name__)
app.debug = True

# 内部其实就有个判断,初始值是FALSE,第一次执行后将值改变为True,以后判断后就不执行了
@app.before_first_request
def before_first_request2():
    print(‘before_first_request2‘)

if __name__ == ‘__main__‘:
    app.run()

10. 中间件

前面关于请求的中间件已经在请求扩展里讲了。

由于知道请求之前会执行一个wsgi_app,所以这里做个请求之前的定制,先了解一下

from flask import Flask
app = Flask(__name__)

@app.route("/login", methods=[‘GET‘, ‘POST‘])
def index():
    pass

class Md(object):
    def __init__(self, old_wsgi_app):
        self.old_wsgi_app = old_wsgi_app

    def __call__(self, environ, start_response):
        print("开始之前")
        ret = self.old_wsgi_app(environ, start_response)
        print("结束之后")
        return ret

if __name__ =="__main__":
    app.wsgi_app = Md(app.wsgi_app) # 相当于把wsgi_app给更新了
    app.run()

11.蓝图

前置情景:一个项目一般会有多个.py文件组成,这些.py文件分别执行不同的功能,那就可以为这些不同功能的.py文件给划分到不同的目录里去。

所以蓝图用于为应用提供目录划分:

未使用蓝图的目录结构,但是没有Flask提供的蓝图好,蓝图里还提供了一些类似请求扩展的东西等等。

使用蓝图的目录结构

           

使用蓝图的目标:

1. 构造程序目录

2. 自定义程序目录

  批量处理url

  定制模板路径和静态文件路径

  请求扩展:

    - 可以针对app, 即全部程序都生效

    - 也可以针对单个的蓝图,即只有在执行该蓝图时,请求扩展才会生效

Flask的官方文档可知,蓝图需要掌握的几个方面知识点如下:

1. 注册蓝图

2. 蓝图资源

3. 静态文件

4. 模板

5. 构造URL

原文地址:https://www.cnblogs.com/victorm/p/9460195.html

时间: 2024-10-06 21:58:21

第二篇 Flask基础篇之(闪现,蓝图,请求扩展,中间件)的相关文章

python框架之Flask基础篇(四)-------- 其他操作

1.蓝图 要用蓝图管理项目,需要导入的包是:from flask import Buleprint 具体大致分为三步: 1.先在子模块中导入蓝图包,然后再创建蓝图对象. 2.然后将子模块中的视图函数存储在蓝图对象中. 3.最后在主模块的文件夹里注册蓝图. 下面分别展示以上三步在项目中的具体操作: 第一步: 第二步: 第三步: 在子模块中运用模版:需要两步. 第一: 先要在pycharm中设置一下: 第二: 然后需要在创建蓝图对象的时候需要手动加上下面这句话: 前面那句话的意思是给url加上一个前

python框架之Flask基础篇(二)-------- 数据库的操作

1.flask连接数据库的四步: 倒入第三方数据库扩展包:from flask_sqlalchemy import SQLAlchemy 配置config属性,连接数据库: app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:[email protected]/first_flask"app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 创

python框架之Flask基础篇(一)

一.第一个hello world程序 # coding=utf-8 from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run(debug=True) 1.app参数的设置: 以下几种方式全部拿debug模式举例: .方式一:将参数设置到app.config字典中: app.conf

CI框架篇之基础篇(1)

CodeIgniter 是一套给 PHP 网站开发者使用的应用程序开发框架和工具包.它提供一套丰富的标准库以及简单的接口和逻辑结构, 其目的是使开发人员更快速地进行项目开发.使用 CodeIgniter 可以减少代码的编写量 ,并将你的精力投入到项目的创造性开发上. CodeIgniter 是为谁准备的? CodeIgniter 就是你所需要的,如果... 你想要一个小巧的框架. 你需要出色的性能. 你需要广泛兼容标准主机上的各种 PHP 版本和配置. 你想要一个几乎只需 0 配置的框架. 你想

CI框架篇之基础篇(2)

CodeIgniter 的基础了解了后,现在就来对这个框架进行预热 CodeIgniter 配置 理论是不用配置,直接拷贝到服务器目录下即可运行 CodeIgniter 安装分为四个步骤: 1. 解压缩安装包. 得到如图所示的文件目录: 2. 把 CodeIgniter  文件夹和里面的文件上传到你的服务器.通常 index.php 在根目录. 3. 用任何文本编辑器打开 application/config/config.php 去设置你的网站根 URL.如果你打算使用加密或 Session,

学习爬虫看着篇(基础篇)

1.爬虫的定义 网络爬虫(又称网络蜘蛛)模拟客户端发送网络请求,接收请求响应,自动的进行抓取网络数据的程度. 注意: 网络爬虫在进行抓取数据的时候并不能进行辨别信息真伪(比如某直播平台直播房间显示在线观看人数100w,在这个数量上会有一些是运营商加上去的数据,比如真正在线人数80w运营商再加上去20w,网络爬虫抓取的就是100w和用户在浏览器中看到的一样)网络爬虫仅仅是可以爬到用户在浏览器可以看到的. 2.爬虫的目的 1.建立网站 进行数据展示 (某新闻网) ? 某新闻网,并不是做新闻的公司,用

django的orm操作篇(基础篇)

# 获取个数 # # models.Tb1.objects.filter(name='seven').count() # 大于,小于 # # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值 # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值 # models.Tb1.objects.filter(id__lt=10)             #

Flask框架(二)—— 反向解析、配置信息、路由系统、模板、请求响应、闪现、请求扩展、session

目录 反向解析.配置信息.路由系统.模板.请求响应.闪现.session 一.反向解析 1.什么是反向解析 2.使用 二.配置信息 1.默认配置 2.修改方法一--点的方式修改 3.修改方法二--利用字典修改 4.修改方法三--通过py文件修改(常用) 5.修改方法四--利用类或类的路径修改(常用) 6.其他方法修改配置 三.路由系统 1.基本写法 2.转换器 3.路由本质 4.CBV 5.自定义支持正则 四.模板 五.请求与响应 六.session 七.闪现(flash) 1.使用 2.示例

java基础篇---I/O技术(三)

接上一篇java基础篇---I/O技术(二) Java对象的序列化和反序列化 什么叫对象的序列化和反序列化 要想完成对象的输入或输出,还必须依靠对象输出流(ObjectOutputStream)和对象输入流(ObjectInputStream).使用对象输出流输出序列化对象的步骤,有时也成序列化,而使用对象输入流读入对象的过程,有时也称为反序列化 一个对象产生之后实际上是在内存中为其开辟了一个存储空间,方便存储信息. 对象序列化就是把一个对象变成二进制的数据流的一个方法,通过对象序列化可以反驳的