一、视图
1、route
(1)路由:
将从客户端发送过来的请求分发到指定函数上
(2)语法:
@app.route(‘/rule/’) def hello(): return ‘Hello World!’ @app.route(‘/rule/<id>/’) def hello(id): return ‘Hello{}’.format(id)
(3)route规则
写法 <converter:variable_name> converter类型 string 接收任何没有斜杠(‘/’)的文件(默认) int 接收整型 float 接收浮点型 path 接收路径,可接收斜线(’/’) uuid 只接受uuid字符串,唯一码,一种生成规则 any 可以同时指定多种路径,进行限定
@blue.route('/getany/<any(a, b):an>/') def get_any(an): print(an) print(type(an)) return 'Any succes'
(4)请求方法
@app.route(‘/rule/’,methods=[‘GET’,’POST’]) def hello(): return ‘LOL’
methods中指定请求方法:
GET
POST
HEAD
PUT
DELETE
@blue.route('/getrequest/', methods=["GET", "POST", "PUT", "DELETE"]) def get_request(): print(request.host) print(request.url) if request.method == "GET": return "GET Success %s" % request.remote_addr elif request.method.lower() == "post": return "POST Success" else: return '%s Not Support' % request.method
(5)反向解析url_for
根据函数名,获取反向路径
url_for('函数名', 参数名=value) # 如果是用蓝图,则蓝图名.函数名
@blue.route('/redirect/') def red(): # return redirect('/') return redirect(url_for('blue.get_any', an='a'))
2、request
服务器在接收到客户端的请求后,会自动创建Request对象
由Flask框架创建,Request对象不可修改
(1)属性
url 完整请求地址
base_url 去掉GET参数的URL
host_url 只有主机和端口号的URL
path 路由中的路径
method 请求方法
remote_addr 请求的客户端地址
args GET请求参数,并不是get专属,所有请求都能获取这个参数
form POST请求参数,直接支持put和patch
files 文件上传
headers 请求头
cookies 请求中的cookie
(2)ImmutableMultiDict
类似字典的数据结构,与字典的区别,可以存在相同的键
args和form都是ImmutableMultiDict的对象
ImmutableMultiDict中数据获取方式:
dict['uname'] 或 dict.get('uname)
获取指定key对应的所有值:
dict.getlist('uname')
3、response
服务器返回会给客户端的数据,由程序员创建,返回Response对象
(1)返回方式
a、直接返回Response对象
from flask import Blueprint, render_template, request, Response blue = Blueprint('app', __name__) @blue.route('/getresponse/') def get_response(): return Response("自己造一个DIY")
b、通过make_response(data,code)
- data 返回的数据内容
- code 状态码
@blue.route('/getresponse/') def get_response(): response = make_response("<h2>哈哈哈</h2>")return response
c、返回文本内容,状态码
@blue.route('/getresponse/') def get_response(): return 'Hello Sleeping', 400
d、返回模板(本质和3一样)
@blue.route('/getresponse/') def get_response(): result = render_template('h1.html') return result
(2)重定向
@blue.route('/getresponse/') def get_response(): return redirect(url_for('app.hi'))
(3)终止处理以及异常捕获
a、终止执行(主动终止)
abort(code) #code只能是系统定义的错误码
b、捕获异常
@app.errorhandler(404) def hello(): return ‘LOL’
完整示例:
@blue.route('/getresponse/') def get_response(): abort(404) return redirect(url_for('app.hi')) @blue.errorhandler(404) def hello(e): return "这是异常页面 %s" % e
二、会话
1、cookie
客户端端的会话技术,flask中的cookie默认对中文等进行了处理,直接可以使用中文
cookie本身由浏览器保存,通过Response将cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带cookie过来
response.set_cookie(key,value[,max_age=None,exprise=None)]
request.cookie.get(key)
max_age: 整数,指定cookie过期时间
expries : 整数,指定过期时间,可以指定一个具体日期时间
max_age和expries两个选一个指定
过期时间的几个关键时间
max_age 设置为 0 浏览器关闭失效
设置为None永不过期
删除cookie
response.delete_cookie(key)
cookie不能跨域名
cookie不能跨浏览器
@blue.route('/login/', methods=[ "POST"]) def login(): username = request.form.get("username") response = Response("登录成功%s" % username) response.set_cookie('username', username) return response
@blue.route('/mine/')
def mine():
username = request.cookies.get('username')
return '欢迎回来:%s' % username
2、session
服务端会话技术,数据存储在服务器,在flask中,将session存在cookie中,对数据进行序列化,base64,zlib压缩,产地了hash.
flask-session实现了服务端session,将数据存储服务端,将数据对应的key存储在cookie中
默认过期时间是31天
@blue.route('/login/', methods=[ "POST"]) def login(): username = request.form.get("username") response = Response("登录成功%s" % username) session['username'] = username session['password'] = "110" return response @blue.route('/mine/') def mine(): username = session.get('username') return '欢迎回来:%s' % username
注意:在flask中使用session需要设置SECRET_KEY(在配置文件中)
将session存入到redis中
class Config: DEBUG = False TESTING = False SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY = "Rockdafafafafafa" # 将session存储在redis中 SESSION_TYPE = "redis" REDIS_HOST = "110.110.110.110" REDIS_PORT = "6379" REDIS_DB = 0 # session长期有效,则设定session生命周期,整数秒 ERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # 是否强制加盐,混淆session SESSION_USE_SIGNER = True # sessons是否长期有效,false,则关闭浏览器,session失效 SESSION_PERMANENT = False SESSION_REDIS = StrictRedis(host=REDIS_HOST, port=REDIS_PORT) SESSION_COOKIE_SECURE = True
三、模板
1、jinjia2
Flask中使用Jinja2模板引擎,Jinja2由Flask作者开发一个现代化设计和友好的Python模板语言,模仿Django的模板引擎
优点:
速度快,被广泛使用
HTML设计和后端Python分离
减少Python复杂度
非常灵活,快速和安全
提供了控制,继承等高级功能
2、模板中的语法
(1)变量
模板中的变量 {{ var }},视图传递给模板的数据前面定义出来的数据变量不存在,默认忽略
(2)标签
模板中的标签{% tag %}
控制逻辑
使用外部表达式
创建变量
宏定义
@blue.route('/students/') def students(): student_list = ["小明 %d" % i for i in range(10)] return render_template('Students.html', student_list=student_list, a=5, b=5)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>StudentList</title> </head> <body> <ul> {% for student in student_list %} <li>{{ student }}</li> {% endfor %} </ul> <hr> {% if a==b %} <h1>这这是条件判断</h1> {% endif %} <hr> </body> </html>
3、结构标签
(1)block
{% block xxx %}
{% endblock %}
块操作
父模板挖坑,子模板填坑
(2)extends
{% extends ‘xxx’ %} 继承后保留块中的内容 {{ super() }}
挖坑填坑体现的是化整为零的效果
(3)include
{% include ’xxx’ %} 包含,将其他html包含进来,体现的是由零到一的概念 (4)marco
{% marco hello(name) %} {{ name }} {% endmarco %} 宏定义,可以在模板中定义函数,在其它地方调用 宏定义可导入 {% from ‘xxx’ import xxx %}
{% extends 'user/base_user.html' %} {% block header %} {% include 'banner.html' %} {% endblock %} {% block content %} <h2>这是用户注册的内容</h2> {% macro hello() %} <h3>这是一个macro</h3> {% endmacro %} {{ hello() }} {{ hello() }} {{ hello() }} {{ hello() }} {{ hello() }} {{ hello() }} {{ hello() }} {{ hello() }} {{ hello() }} {% endblock %}
4、循环
for
{% for item in cols %}
AA
{% else %}
BB
{% endfor %}
可以使用和Python一样的for…else
也可以获取循环信息 loop
loop.first
loop.last
loop.indexloop.index0
loop.revindexloop.revindex0
5、过滤器
语法
{{ 变量|过滤器|过滤器… }}
capitalize
lower
upper
title
trim
reverse
format
striptags 渲染之前,将值中标签去掉
safe
default
last
first
length
sum
sort
6、模板路径以及静态资源路径
(1)、模板
模板路径默认在Flask(app)创建的路径下,如果想自己指定模板路径,在Flask创建的时候,指定template_folder,同时也可以在蓝图创建的时候,指定template_folder,蓝图也可以指定统一前缀/xx。
模板中模板中使用反向解析和在python代码中一样,使用url_for
(2)、静态资源
静态资源在Flask中是默认支持的,默认路径在和Flask同级别的static中,想要自己指定可以在Flask创建的时候指定 static_folder,也可以在蓝图中指定,静态资源也是有路由的endpoint是 static,参数有一个filename
{{ url_for('static', filename='xxx') }}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> {# <link rel="stylesheet" href="/static/css/hi.css">#} <link rel="stylesheet" href="{{ url_for('static', filename='css/hi.css') }}"> </head> <body> <h1>天气寒冷</h1> <ul> <li>今天雾霾</li> <li>下雨了</li> <li>{{ msg }}</li> </ul> </body> </html>