首页 > 技术文章 > Flask入门

haowen980 2018-09-05 21:35 原文

Flask与Django对比 :
django:
  1. 大而全,admin, models, Formm, 中间件
  2. 一个框架解决所有问题
缺点:

1.一旦启动,所有资源全部加载,用户到的,浪费了。

  1. 太大了,结构复杂
  2. 所有组件,全部由Django自身控制
Flask:
  1. 轻,短小精悍
  2. 快,三行代码开启服务
缺点:
  1. 组件大部分来源域三方,flask-admin,flask-session
  2. flask 大版本更新组件,组件更新速度慢
Tornado
  1. 原生websocket
  2. 异步IO
  3. 非阻塞
  4. 原生SQL
缺点

三方以及原生组件,几乎为0

Flask开始使用
  1. 三行帅哥版
from flask import Flask  #导入flask

app = Flask(__name__)#实例化flask对象
app.run("0.0.0.0",5000,debug=True) #运行flask
  1. 六行上进青年版
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) 
  1. 精英版
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 !"
Flask中HTTPResponse
from flask import Flask,redirect      #导入flask中的redirect

@app.route("/redi")             #app中的route装饰器,用来指定视图函数的URL地址
def redi(): #视图函数
    return redirect("/")    #redirect跳转至"/"
##当访问"/redi"这个地址的时候,视图函数redi会触发redirect("/") 跳转到url地址:  "/" 并会触发"/"对应的视图函数index()
Flask中的Redirect
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 %}

  

接下来,我们对这几种情况分别进行传递,并在前端显示成表格 

  1. 使用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的对象操作 

  1. 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就是列表中的每一个字典,再使用各种取值方式取出值即可。 

  1. 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 

  1. 结合所有的字符串儿全部专递前端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中可以传递多个关键字

  

推荐阅读