初识Flask
Flask介绍
轻量级的框架
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。
Flask和Django的比较:
Django:
优势 -- 组件全,有admin,ORM,Form等。
劣势 -- 运行需加载所有组件,占用资源较高,重型框架
Flask:
优势 -- 轻型框架,扩展性极强,三方组件多
劣势 -- 什么组件都没有,三方组件多,导致版本兼容不稳定
Flask 安装 + 启动
最简单的启动: from flask import Flask app = Flask(__name__) app.run() 高级启动: from flask import Flask app = Flask(__name__) @app.route("/") def home(): return "Hello World!" app.run()
Flask Response
Django | Flask |
HttpResponse("HelloWorld") | "HelloWorld" 返回字符串 |
render("模板路径") | render_template 返回模板 |
redirect("/") | redirect("/") |
Flask 中的返回特殊封装
1.jsonify 转换标准JSON格式
响应头中加入 Content-type:application/json
在Flask 1.1.1 版本中 加入了 直接返回字典 可以不再使用jsonify了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, render_template, redirect, jsonify, send_file @app.route('/json') def my_jsonify(): return jsonify({'a': 1}) # 在Flask 1.1.1版本中,直接返回字典也是可以的 @app.route('/json') def my_jsonify(): return {'name': 'alex'}
2.send_file 发送文件
打开并返回文件内容,
自动识别文件类型,
响应头中加入Content-type:文件类型
ps:当浏览器无法识别Content-type时,会下载文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, render_template, redirect, jsonify, send_file @app.route('/file') def file(): return send_file('1.mp3') # 不止可以是mp3,各种格式都可以,不过如果浏览器不识别就会自动下载。 # 比如zip,rar等压缩文件在谷歌浏览器就会是下载~
Flask Request
405 请求方式不被允许
- GET请求可以
- POST请求 405 Method Not Allowed
关于request
from flask import request # 公共对象 # 重要的!!! 1.request.form # 获取FormData中的数据(Form表单) 2.request.args # 获取URL中的参数 3.request.files # 获取FormData中的文件数据 print(request.url) # 获取访问路径 print(request.method) # 获取请求方式 print(request.path) # 路由地址 /login print(request.values) # 综合获取 Form 和 Args 中的数据 print(request.args.get("id")) # 获取URL中的参数 print(request.args["id"]) # 获取URL中的参数 print(request.args.to_dict()) # 获取URL中的参数 转换成 字典 print(request.environ) # 获取请求原始信息 print(request.base_url) # 获取URL头,不包含参数 print(request.json) # 毁三观 1 请求头中 Content-type:application/json 数据序列化 request.json print(request.data) # 毁三观 2 请求头中 Content-type 不包含 Form or data print(request.headers) # 请求头中的数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, render_template, request app = Flask(__name__) app.debug = True @app.route('/login', methods=['POST', 'GET']) def login(): if request.method == 'GET': # print(request.url) # http://127.0.0.1:5000/login?a=1 # print(request.args) # ImmutableMultiDict([('a', '1')]) # print(request.base_url) # http://127.0.0.1:5000/login # print(request.path) # /login # print(request.values) # CombinedMultiDict([ImmutableMultiDict([('a', '1')]), ImmutableMultiDict([])]) # print(request.environ) # 获取请求原始信息 # print(request.json) # None # print(request.data) # b'' # print(request.headers) # 请求头中的数据 return render_template('login.html') else: print(request.form.to_dict()) # print(request.headers) print(request.values.to_dict()) # {'username': 'alex', 'pwd': 'alex3714', 'a': '1'} username = request.form.get("username") password = request.form.get("pwd") print(request.files.get("my_file")) my_file = request.files.get("my_file") my_file.save(my_file.filename) # 文件保存 if username == 'alex' and password == "alex3714": return '登录成功' else: return "登录失败" if __name__ == '__main__': app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="pwd"> <input type="file" name="my_file"> <input type="submit"> </form> </body> </html>
Jinja2
{{}} - 引用或者执行
{%%} - 逻辑语法(if else for)
# 和Django用法差不多,不止可以点取到数据,也可以通过字典的get或者中括号取数据。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, render_template STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'}, {'name': 'Boy', 'age': 73, 'gender': '男'}, {'name': 'EDU', 'age': 84, 'gender': '女'} ] STUDENT_DICT = { 1: {'name': 'Old', 'age': 38, 'gender': '中'}, 2: {'name': 'Boy', 'age': 73, 'gender': '男'}, 3: {'name': 'EDU', 'age': 84, 'gender': '女'}, } app = Flask(__name__) app.debug = True @app.route('/index') def index(): return render_template('index.html', st=STUDENT, s_list=STUDENT_LIST, s_dict=STUDENT_DICT) if __name__ == '__main__': app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Student</title> </head> <body> <h1>Hello World</h1> <table border="1"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> <tr> <td>{{ st.name }}</td> <td>{{ st.get('age') }}</td> <td>{{ st['gender'] }}</td> </tr> </table> <hr> <table border="1"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for s in s_list %} <tr> <td>{{ s.name }}</td> <td>{{ s.get('age') }}</td> <td> {% if s['gender'] != "男" and s['gender'] != "女" %} 女 {% else %} {{ s.gender }} {% endif %} </td> </tr> {% endfor %} </table> <hr> <table border="1"> <tr> <td>id</td> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for id,s in s_dict.items() %} <tr> <td>{{ id }}</td> <td>{{ s.name }}</td> <td>{{ s.age }}</td> <td> {% if s.gender !="男" and s.gender != "女" %} 女 {% else %} {{ s.gender }} {% endif %} </td> </tr> {% endfor %} </table> </body> </html>
Flask中的Session
这里的Session不是三方组件,不是Flask-Session
session 交由客户端保管机制
反序列化机制
当客户端发起请求 - request 带上 Cookie - Cookie中有session的加密字符串 - Flask 收到Session加密字符串 - 通过secret_key解密session的加密字符串 - 获得 {username:123}
序列化机制
- 开启session - session["username"] = uname - 先创建一个字典 {username:123} 接下来 通过secret_key + 时间戳 + 签名 加密 形成session的加密字符串
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, request, render_template, redirect, session STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'}, {'name': 'Boy', 'age': 73, 'gender': '男'}, {'name': 'EDU', 'age': 84, 'gender': '女'} ] STUDENT_DICT = { 1: {'name': 'Old', 'age': 38, 'gender': '中'}, 2: {'name': 'Boy', 'age': 73, 'gender': '男'}, 3: {'name': 'EDU', 'age': 84, 'gender': '女'}, } app = Flask(__name__) app.debug = True app.secret_key = '$%^$##^&T(U)(&(&' @app.route('/login', methods=['POST', 'GET']) def login(): if request.method == "GET": return render_template('login.html') username = request.form.get('username') password = request.form.get("pwd") if username == '123' and password == "123": session['username'] = username return 'Success' else: return 'False' @app.route("/detail") def detail(): if session.get('username'): return render_template("index.html", st=STUDENT, s_list=STUDENT_LIST, s_dict=STUDENT_DICT) else: return redirect('/login') if __name__ == '__main__': app.run()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username"> 密码:<input type="password" name="pwd"> <input type="file" name="my_file"> <input type="submit"> </form> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Student</title> </head> <body> <h1>Hello World</h1> <table border="1"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> <tr> <td>{{ st.name }}</td> <td>{{ st.get('age') }}</td> <td>{{ st['gender'] }}</td> </tr> </table> <hr> <table border="1"> <tr> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for s in s_list %} <tr> <td>{{ s.name }}</td> <td>{{ s.get('age') }}</td> <td> {% if s['gender'] != "男" and s['gender'] != "女" %} 女 {% else %} {{ s.gender }} {% endif %} </td> </tr> {% endfor %} </table> <hr> <table border="1"> <tr> <td>id</td> <td>name</td> <td>age</td> <td>gender</td> </tr> {% for id,s in s_dict.items() %} <tr> <td>{{ id }}</td> <td>{{ s.name }}</td> <td>{{ s.age }}</td> <td> {% if s.gender !="男" and s.gender != "女" %} 女 {% else %} {{ s.gender }} {% endif %} </td> </tr> {% endfor %} </table> </body> </html>