vlambda博客
学习文章列表

#Flask 30(第三篇v2) 请求钩子、模板语言

:路由(路由、配置等)

:视图(request、cookie&session、jsonify)

本篇:请求钩子、模板语言(变量+过滤器)

请求钩子

本质:在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要统一处理。目的:让每个视图函数避免编写重复功能的代码(可以理解成Django中的中间件)

四种常用请求钩子:

  • before_first_request:处理app第一个请求前运行。

  • before_request:在每次请求前运行。

  • after_request:如果处理逻辑没有异常抛出,在每次视图函数处理完之后都被执行

  • teardown_request:在每次视图函数处理完之后都被执行,无论是否有异常发生(工作在Debug=False)

from flask import Flask

app = Flask(__name__)

@app.route('/')
def helloworld():
    return 'hello world'

# 在第一次请求之前运行,比如连接数据库操作只需要执行一次
@app.before_first_request
def before_first_request():
    print('before_first_request')

# 在每一次请求都会执行,可以在这里做权限校验操作,比如说某用户是黑名单用户,黑名单用户登录系统将遭到拒绝访问
@app.before_request
def before_request():
    print('before_request')

# 在请求之后运行
@app.after_request
def after_request(response):
    # response: 就是前面的请求处理完毕之后, 返回的响应数据
    print('after_request')
    return response

# 每一次请求之后都会调用,会接受一个参数,参数是服务器出现的错误信息
@app.teardown_request
def teardown_request(error):
    print('teardown_request: error %s' % error)
    if path in [url_for(index),url_for(order)]:
        ....  # 某一些路径下的视图函数集中做处理
        
if __name__ == '__main__':
    app.run(debug=False)

模板语言

from flask import Flask,render_template

app = Flask(__name__)

@app.route('/index')
def index():
    return render_template('index.html',name='egg',age=39)
    # 第一个参数是模板的页面,后面的参数是把要传的变量平铺开

1、变量

data = {
        'name':'egg',            #{{name}}
        'my_dict':{'city':'fz'}, #{{my_dict.city}}
        'my_list':[1,2,3,4],     #{{my_list}};{{my_list.1}};
    }
#django中{{}}这里面的变量不支持直接相加,但flask支持:{{my_list.1+my_list.2}},也支持字符串相加(即拼接)

2、过滤器

{{变量 |trim|upper}} 支持链式使用过滤器

safe:禁用转义
capitalize:首字母大写,其余小写
lower:全转小写
upper:全转大写
title:每个单词首字母转大写
trim:首尾空格去掉
reverse:字符串反转(hello变成olleh)
format:格式化输出{{'%s is %d' | format('name',39)}}

3、列表过滤器

first:取第一个元素{{[1,3,4,5] | first}}
last:取最后一个元素
length:获取列表长度{{[1,3,4,5] | length}}
sum:列表求和{{[1,3,4,5] | sum}}
sort:列表排序{{[1,3,4,5] | sort}}

4、自定义过滤器

a.本质上是写一个函数。

  • 函数有一个传入的参数,就是这个要处理的变量{{变量...}}
  • 函数return的结果是{{}}最后输出的结果

b.写完函数后flask并不知道他的存在,要注册过滤器(告诉flask我的存在)

#第一种注册过滤器的方式:
def list_step_2(li):  # 这是一个对列表隔一个值取值的自定义过滤器
    return li[::2]

app.add_template_filter(list_step_2,"li2"# 注册过滤器,两个参数:函数名,过滤器名称

-------------------------------

#第二种注册过滤器的方式:(注意看,不是@app.add_template_filter('li2'))
@app.template_filter('li2')
def list_step_2(li):
    return li[::2]
    
---------------------------------

模板中这么使用{{my_list | li2}}


5、模版语言中的执行语句是{%...%} ,很好记:两个%像两个车轮一样在run,所以是可执行的语句。而变量,或者是函数调用(结果也是返回一个值的),都是用{{...}}

6、模版渲染的时候有一些变量和方法是可以直接{{...}}这样使用的,有:config对象、request对象,url_for()方法,get_flashed_messages()方法


7、模板闪现:get_flashed_messages()方法细说一下,在后端from flask import Flask,flash有个flash()函数,可以把"需要给前端展示的信息"塞到flash中,比如flash('用户名不能为空'),然后在模板中可以直接通过{{get_flashed_messages()}}来提取flash中的信息。这个信息只能在此次请求中提取,下次请求来的时候flash就是清空状态的,相当于一个数据的临时存放点。(底层需要用到session,SECRET_KEY需要设置值)


模板宏

模板宏类似于函数的概念,可以在模板中重复利用代码,避免冗余.

# 定义:
{% macro input() %}
<input type="text" value="">
{%...此处可以有可执行语句...%}
{% endmacro %}

# 使用:
{{input()}}
变形1:可以传参
{% macro input(type,value,szie) %}
<input type="{{type}}" value="{{value}}">
{% endmacro %}

{{input('password','aaa')}}
---------------------------------

变形2:可以提供默认值
{% macro input(type="text",value="111") %}
<input type="{{type}}" value="{{value}}" >
{% endmacro %}

{{input('password','aaa')}}
{{input()}}
--------------------------------------

变形3:可以把宏定义在外部,即:专门用一个html文件(macro_input.html)只写宏的内容(与前面变形2内容一致)
{% import "macro_input.html" as m_input %}
{{ m_input.input()}}    


此外,模板的知识点还有:模板继承、模板包含(include);这里写的比较粗糙,具体使用具体查