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中可以传递多个关键字