flask框架(二)
1.cookie(掌握)
掌握的内容需要会敲。
解释:用来保持服务器和浏览器交互的状态。有服务器设置,存储在浏览器里面。
作用:用来做广告的推送。
cookie的设置和获取
设置cookie:response.set_cookie(key,value,max_age)
max_age
表示cookie在浏览器的存储时间,单位是秒
如果不设置max_age
那么默认的有效期就是当前浏览器关闭的时候
获取cookie:request.cookies.get("key")
2.session(理解)
解释:服务器和用户来做状态保持的,里面存储的是敏感信息(比如身份证,登录信息),有服务器设置,并存储在服务器
作用:用来做用户的登录状态保持。
session的设置和获取
设置session:session[key] = value
获取session:value = session.get(key)
注意点:
session的存储依赖于cookie
存储在cookie中的sessionID需要加密,需要秘钥(SECRET_KET)
3.上下文(了解)
current_app功能开发(获取数据库连接、日志)
解释:就是一个容器
请求上下文
request
:封装的是请求相关的数据(是客户端中存储的)
session
:封装的是和用户相关的敏感信息(是服务器存储的)
应用上下文(在项目中具体应用)
current_app
:是app的一个代理对象,可以通过他获取app身上设置的各种属性,主要用在模块开发中,current_app
是全局的,每来一个客户端,app就开通一个current_app
。g
对象存储current_app
的服务信息。服务完毕后,自动销毁。
g
:一个局部的全局变量,主要用在装饰器中
好比我们去吃自助餐,老板app
不可能服务我们每一个人,老板会让服务员current_app
来服务我们,每个人都会有一个服务员来进行接待,我们想吃东西,会拿一个盘子g
来装东西,当我们吃完,盘子g
会进行一个回收。
4.Flask_Script(掌握)
解释:属于Flask的扩展
作用:用来动态运行一个程序,配合flask_migrate做数据库迁移
使用格式:
1、安装:pip install flask_script
2、导入Manager类
3、创建对象manager管理app
在启动程序的时候就不能写app.run(debug=True)
而是写manager.run()
括号里面不能在写debug,因为它没有这个参数。开启debug看后面。
开启debug也可以在创建对象之前加入:app.config[DEBUG]=True
也可以开启debug
4、使用manager启动程序
启动命令:python xxx.py runserver -h(host是IP地址) -p(端口号) -d(调试模式)
运行过程可以指定参数
加-d
代表的就是debug,不需要再写其他的内容。
5.render_template(掌握)
属于jinja2模板
业务逻辑就是数据库的增删改查
解释:属于jinja2的模板函数
好处:
1、以后的视图函数,只负责业务逻辑的处理,比如:数据库的增删改查
2、以后数据的展示,全部都有jinja2的模板负责
使用格式:
response=render_template('模板文件')
模板文件就是html文件。
render_template
会将所有内容转换成字符串,打包成响应体,返回给response,浏览器直接读取即可。
模板文件必须写在templates
文件夹下面,需要新建文件夹
高内聚,低耦合:
所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。
对于低耦合,粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。
6.模板语法,获取变量(理解)
解释:在模板中获取视图函数的变量
格式:
{{ 变量 }}
变量可以是任何类型的数据
变量分开获取的方式
tuple[0]
和tuple.1
list.0
和list.1
dict.name
dict["age"]
如果字典使用方括号,获取,需要写成字符串,如果不是字符串,那么则会被当成变量对待.
地址被占用,解决方法:
终端里面杀死端口
lsof -i:5000
kill PID(占用端口号的程序的PID)
7模板语法,分支循环判断(掌握)
模板语法的种类
分支格式:
{% if 条件 %}
语句1
{% else %}
语句2
{% endif %}
循环格式语法:
{% for 变量 in 容器 %}
{% endfor %}
注释:
{# 这里是注释的内容 #}
pycharm中想让html文件输入内容有提示,可以将templates文件夹改成jinja2的格式,支持模糊匹配
选择templates文件夹----右键----点击Mark directory as------选择Template Forlder----跳出的框里面选jinja2
快捷键:pycharm中写html文件,for + tab键可以快速创建for循环。
dict.key
那么这个key会当成字典中的一个键,dict[key]
,那么这个key当成一个变量
8.系统字符串过滤器(理解)
解释:过滤器,过滤一些你想要的数据
格式:{{ 字符串 | 字符串过滤器}}
常见的字符串过滤器有:
记住:reverse,其他有印象即可
safe:禁用转义
<p>{{ '<em>hello</em>'|safe }}</p>
capitalize:把变量值的首字母转成大写,其余字母转小写
“hello PYTHON”会将整体看成一个字符串,只将h变大写
<p>{{ 'hello'|capitalize }}</p>
lower:把值转成小写
如果值里面有汉字,汉字不会变,汉字没有大小写
<p>{{ 'HELLO'|lower }}</p>
upper:把值转成大写
<p>{{ 'hello'|upper }}</p>
title:把值中的每个单词的首字母都转成大写
<p>{{ 'hello'|title }}</p>
reverse:字符串反转
中文是可以反转的
<p>{{ 'olleh'|reverse }}</p>
format:格式化输出
可以将name和17替换占位符
<p>{{ '%s is %d'|format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>'|striptags }}</p>
em代表的是斜体(h5里面的)
9.系统列表过滤器(理解)
解释:过滤器,过滤一些你想要的数值
格式:{{ 列表 | 列表过滤器}}
常见的列表过滤器有:
first:取第一个元素
<p>{{ [1,2,3,4,5,6] |first }}</p>
last:取最后一个元素
<p>{{ [1,2,3,4,5,6] |last }}</p>
length:获取列表长度
<p>{{ [1,2,3,4,5,6] |length }}</p>
sum:列表求和
<p>{{ [1,2,3,4,5,6] |sum }}</p>
sort:列表排序
默认是升序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
过滤器支持链式调用
10.自定义过滤器(掌握)
解释:当系统提供的过滤器满足不了需求的时候,需要自定义
自定义过滤器有两种格式:
1、先定义好函数,再将函数添加到系统默认的过滤器列表中
def 函数名:pass
app.add_template_filter(函数名,‘过滤器名字’)
2、定义函数的时候,直接使用系统过滤器进行装饰
@app.template_filter('过滤器名字')
def函数名():
pass
案例:
1、获取列表偶数和
列表过滤器里面没有反转,但是python里面的列表有反转的方法。
升序,再反转就可以实现降序。
2、反转字符串
11.代码复用之宏(了解)
解释:相当于python中的函数,定义好一段功能,在需要的时候进行调用即可
定义格式:
{%macro宏名(参数)%}
{%endmacro%}
使用格式:
//使用当前文件定义好的宏
{{ 宏名(参数) }}
//使用其他文件定义好的宏
{%import'文件'as别名%}
{{ 别名.宏名(参数)}}
因为有些功能要重复使用,频率很高,所以可以封装成宏,就可以直接调用了.
12.代码复用之继承(掌握)
解释:一个子模板继承自父模板
作用:共性抽取,代码复用
父模板
1.所有子类都具有的相同的内容的,在父模板中就直接写死
2.每个子类的模板中不一样的内容,使用block模块定义好.
子模板
1.根据子类自己的需求,去重写父类中的block对应的内容
2.如果重写之后,还想保留父类的内容,那么使用{{ super }}
3.继承格式:{% extends '父类文件名' %}
,写在页面的顶部
4.重写父类:
{%block要重写部分的名称%}
内容
{%endblock%}
注意:
定义block的格式
{%block名称%}
内容
{%endblock%}
13.代码复用之包含(了解)
解释:在一个文件中完全拥有另外一个文件,不够灵活,没办法扩展
格式:
# 方式一
{%include'文件'%}
# 方式二
{%include'文件'ignoremissing%}
注意点:ignore missing
如果包含的文件不存在,不会报错
14.模板使用练习(掌握)
loop.index0
代表的是遍历的时候可以获取到从0开始的索引
loop.index
从1开始
15.模板特有变量(了解)
解释:不需要通过python程序传递就可以直接使用的变量
常见的特有变量如下:
config
:就是flask中的app.config,表示应用程序中的所有配置信息.app.config
里面的信息
request
:表示请求上下文对象,封装的是请求相关的数据
g
局部的全局变量(了解)
url_for()
:反解析,通过函数的名字,解析到视图函数的路径
url_for("视图函数",key:value)
get_flasked_messages()
:用来消耗flash方法中存储的消息.
场景:登录出错,可以显示
注意点:使用flash存储消息的时候需要设置SECRET_KET,因为flash内部的消息存储,依赖于session.
看pycharm中的html文件中命令有没有提示,如果没有,检查文件夹有没有被设置为jinja2模式,还有看看这个html文件有没有被关联
flash()
的视图函数调用了几次就是往flash(是一个列表)存了几条视图函数里消息,再调用get_flashed_message()
消耗flash里面的消息,一旦消耗,就一次消耗光,不用,就不消耗.
16.csrf攻击流程(了解)
解释:跨站点请求伪造
掌握:需要理解攻击流程图
代码演示:webA(正常网站) webB(黑客网站)
17.csrf攻击手动解决(了解)
解释:
在cookie中增加一个csrf_token
在表单中增加一个csrf_token
校验:取出cookie和表单中的csrf_token比较如果二者一致,那么是正常请求
具体过程看图
18.CSRFProtect解决csrf(理解)
使用流程(要求会用这个流程):
1/安装扩展包pip install flask-wtf
2/导入包from flask-wtf.csrf import CSRFProtect
3/创建CSRFProtect
对象,保护app对象
4/设置SECRET_KEY,便于csrf_token加密
5/需要在表单中设置一个scrf_token即可
例子:注册案例
register.py
1from flask import Flask, render_template, request 2from flask_wtf.csrf import CSRFProtect 3 4app = Flask(__name__) 5 6#设置密码 7app.config["SECRET_KEY"] = "fdffdf" 8 9#保护app 10CSRFProtect(app) 11 12@app.route('/',methods=["GET","POST"]) 13def hello_world(): 14 15 #1.如果是GET请求,直接返回注册页面 16 if request.method == "GET": 17 return render_template("file16register.html") 18 19 else: 20 #2.如果是POST请求,处理注册业务 21 #2.1获取参数 22 username = request.form.get("username") 23 password = request.form.get("password") 24 repassword = request.form.get("repassword") 25 26 #2.2校验参数,为空校验 27 if not all([username,password,repassword]): 28 return "参数填写不全" 29 30 #2.3两次密码是否一致 31 if password != repassword: 32 return "两次密码输入不一致" 33 34 #2.4返回注册成功 35 return "恭喜你, 注册成功" 36 37 38 39if __name__ == '__main__': 40 app.run(debug=True)
register.html
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6</head> 7<body> 8 9<form action="" method="post"> 10 11 {# 只要使用了CSRFProtect保护app,那么可以直接使用csrf_token()方法获取csrf_token值 #} 12 <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> 13 14 用户名:<input type="text" name="username"><br> 15 密码:<input type="password" name="password"><br> 16 确认密码:<input type="password" name="repassword"><br> 17 18 <input type="submit" value="注册"> 19</form> 20 21 22</body> 23</html>
注意点:
1/CSRFProtect一旦保护了app之后,会对POST,PUT,DELETE,PARCH做校验.
all ([username,password,repassword])
[]中任意一个值为空就是false.