Flask入门
Flask与Django对比 :
django:
- 大而全,admin, models, Formm, 中间件
- 一个框架解决所有问题
缺点:
1.一旦启动,所有资源全部加载,用户到的,浪费了。
- 太大了,结构复杂
- 所有组件,全部由Django自身控制
Flask:
- 轻,短小精悍
- 快,三行代码开启服务
缺点:
- 组件大部分来源域三方,flask-admin,flask-session
- flask 大版本更新组件,组件更新速度慢
Tornado
- 原生websocket
- 异步IO
- 非阻塞
- 原生SQL
缺点
三方以及原生组件,几乎为0
Flask开始使用
- 三行帅哥版
from flask import Flask #导入flask app = Flask(__name__)#实例化flask对象
app.run("0.0.0.0",5000,debug=True) #运行flask
- 六行上进青年版
from flask import Flask #导入flask app = Flask(__name__) #实例化flask对象 @app.route("/") def index(): return "Hello world !" app.run("0.0.0.0",5000,debug=True)
- 精英版
from flask import Flask #导入flask app = Flask(__name__) #实例化flask对象 @app.route("/") def index(): return "Heloo word !" app.run("0.0.0.0",9527,debug=True)
网关接口流程
- WSGI:
- socket --- header :{http/1.1/r/nagent}
- socket --- header : {http/1.1/r/nagent}
- Django --- uwsgi
- Flask --- Werkzenug
将请求头做序列化
from werkzeug.wrappers import Request,Response from werkzeug.serving import run_simple @Request.application def app(request): print(request) print(request.method) print(request.url) print(dir(request)) return Response("OK!") run_simple("0.0.0.0",8081,app) #当请求进入服务的时候app + () 运行
1 # 在flask中的HTTPResponse,在我们看来其实就是直接返回字符串 2 3 @app.route("/") #app中的route装饰器 4 def index(): #视图函数 5 return "Hello world !"
from flask import Flask,redirect #导入flask中的redirect @app.route("/redi") #app中的route装饰器,用来指定视图函数的URL地址 def redi(): #视图函数 return redirect("/") #redirect跳转至"/" ##当访问"/redi"这个地址的时候,视图函数redi会触发redirect("/") 跳转到url地址: "/" 并会触发"/"对应的视图函数index()
from flask import render_template #导入flask中的render_template @app.route("/home") #app中的route装饰器,用来指定试图函数的url地址 def home(): #home视图函数 return render_template("home.html") #渲染HTML模版返回HTML页面
HTML模板渲染是每个Web框架中都必须有的,至于render_template的具体用法,留个悬念,往后看
注意: 如果要使用 render_template 返回渲染的模板,请在项目的主目录中加入一个目录 templates
是时候开始写个前端了,Flask中默认的模板语言是Jinja2
现在我们来一步一步的学习一下 Jinja2 捎带手把 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': '女'}, }
但是前提我们要知道Jinja2模板中的流程控制:
I. Jinja2模板语言中的 for
{% for foo in g %} {% endfor %}
II. Jinja2模板语言中的 if
{% if g %} {% elif g %} {% else %} {% endif %}
接下来,我们对这几种情况分别进行传递,并在前端显示成表格
- 使用STUDENT字典传递至前端
后端:
@app.route("/student") def index(): return render_template("student.html",student=STUDENT)
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Old Boy EDU</title> </head> <body> Welcome to Old Boy EDU <div>{{ student }}</div> <table border="1px"> <tr> <td>{{ student.name }}</td> <td>{{ student["age"] }}</td> <td>{{ student.get("gender") }}</td> </tr> </table> </body> </html>
说明:从这个例子中,可以看出来,字典传入前端Jinja2 模板语言中的取值操作, 与Python中的Dict操作极为相似,并且多了一个student.name的对象操作
- STUDENT_LIST 列表传入前端Jinja2 模板的操作:
后端:
@app.route("/student_list") def student_list(): return render_template("student_list.html",student=STUDENT_LIST)
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Old Boy EDU</title> </head> <body> Welcome to Old Boy EDU <div>{{ student }}</div> <table border="1xp"> {% for foo in student %} <tr> <td>{{ foo }}</td> <td>{{ foo.name }}</td> <td>{{ foo.get("age") }}</td> <td>{{ foo["gender"] }}</td> </tr> {% endfor %} </table> </body> </html>
这里我们可以看出如果是需要循环遍历的话,Jinja2 给我们的方案是
{% for foo in student %} <tr> <td>{{ foo }}</td> </tr> {% endfor %}
上述代码中的foo就是列表中的每一个字典,再使用各种取值方式取出值即可。
- STDENT_DICT大字典传入前端Jinja2模版
后端:
@app.route("/student_dict") def student_dict(): return render_template("student_dict.html", student=STUDENT_DICT)
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Old Boy EDU</title> </head> <body> Welcome to Old Boy EDU <table> {% for foo in student %} <tr> <td>{{ foo }}</td> <td>{{ student.get(foo).name }}</td> <td>{{ student[foo].get("age") }}</td> <td>{{ student[foo]["gender"] }}</td> </tr> {% endfor %} </table> </body> </html>
在遍历字典的时候,foo 其实是相当于拿出了字典中的Key
- 结合所有的字符串儿全部专递前端Jinja2 模板
后端:
@app.route("/allstudent") def all_student(): return render_template("all_student.html", student=STUDENT , student_list = STUDENT_LIST, student_dict= STUDENT_DICT)
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Old Boy EDU</title> </head> <body> <div> _____________________________________</div> Welcome to Old Boy EDU : student <div>{{ student }}</div> <table border="1px"> <tr> <td>{{ student.name }}</td> <td>{{ student["age"] }}</td> <td>{{ student.get("gender") }}</td> </tr> </table> <div> _____________________________________</div> Welcome to Old Boy EDU : student_list <div>{{ student_list }}</div> <table border="1xp"> {% for foo in student_list %} <tr> <td>{{ foo }}</td> <td>{{ foo.name }}</td> <td>{{ foo.get("age") }}</td> <td>{{ foo["gender"] }}</td> </tr> {% endfor %} </table> <div> _____________________________________</div> Welcome to Old Boy EDU : student_dict <div>{{ student_dict }}</div> <table border="1xp"> {% for foo in student_dict %} <tr> <td>{{ foo }}</td> <td>{{ student_dict.get(foo).name }}</td> <td>{{ student_dict[foo].get("age") }}</td> <td>{{ student_dict[foo]["gender"] }}</td> </tr> {% endfor %} </table> </body> </html>
这里可以看出来,render_template中可以传递多个关键字