python之初识Flask

Posted 勿忘初心、继续前行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之初识Flask相关的知识,希望对你有一定的参考价值。

一、初识Flask

Python三大主流Web框架对比

1、三大框架的特点

  • Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用得到用不到,反正它全都有,属于全能型框架
  • Tornado 主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架
  • Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架

2、三大框架的优缺点 

  • Django 通常用于大型Web应用由于内置组件足够强大所以使用Django开发可以一气呵成
  • Tornado 通常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真是稳得一批
  • Flask 通常应用于小型应用和快速构建应用,其强大的三方库,足以支撑一个大型的Web应用
  • Django 优点是大而全,缺点也就暴露出来了,这么多的资源一次性全部加载,肯定会造成一部分的资源浪费
  • Tornado 优点是异步,缺点是干净,连个Session都不支持
  • Flask 优点是精悍简单,缺点是组件大都来自第三方等

关于上面的总结

Django:

  优点:

    大而全,admin,models,Form,中间件,session

    一个框架解决所有问题

  缺点:

    一旦启动,所有资源全部加载,用不到的,浪费了

    太大了,结构复杂

    所有的组件,全部由Django自身控制

Flask:

  优点:

    轻、短小精悍

    快、最短三行代码就能开启服务

  缺点:

    组件大部分都来自第三方,如flask-admin, flask-session

    flask大版本更新,组件更新速度慢

 

Tornado:

  优点:

    原生的websocket

    异步io

    非阻塞

  缺点:

    三方和原组件几乎为零

Flask的准备工作

首先我们要安装Flask,具体操作如下:

  pip install Flask   

也可以通过pycharm在里面直接搜索Flask点击安装就好。还有其他的一些安装在这里就不在说了

 

三行代码启动Flask

from flask import Flask
app = Flask(__name__)
app.run()

 

  执行上面的代码我么在控制台可以看到一下一行代码

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

 

从上面可以看出默认访问的端口是5000,

我们访问该页面

上面给我的提示是没有相应的路由,因为我们根本没有配置,不过这个时候服务已经起来了

这个就是三行代码启动Flask服务

 

我们来写一个真正的第一个flask程序

from flask import Flask  # 导入Flask类

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


# url与视图映射
@app.route(\'/\')  # app中的route装饰器
def hello_world():  # 视图函数
    return \'Hello World!\'  # 返回的响应体


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 启动上面代码并访问相应的页面我们在页面上就会看到\'Hello World\'的字样

路由系统

url传参的方式

普通的传参

@app.route(\'/user/<id>/\')  # app中的route装饰器
def hello_world(id):  # 视图函数
    return \'你是第{}个用户\'.format(id)  # 返回的响应体

指定参数类型

有以下几种参数类型:

  • string:默认的数据类型
  • int:接收整型
  • float:浮点型
  • path:和string类似,这里可以接收斜杠
  • any:可以指定多个路径
  • uuid:只接受uuid字符串

(1) any

@app.route(\'/<any(blog,user):url_path>/<id>/\')
def detail(url_path,id):
    if url_path == \'blog\':
        return \'博客详情{}\'.format(id)
    else:
        return \'用户详情{}\'.format(id)

 

 

注意:上面的路由 \'/<any(blog,user):url_path>/<id>/\'写的时候一定要加上\'/\'反斜杠,要不会出错

 (2)path

@app.route(\'/article/<path:test>/\')
def test_article(test):
    return \'test_article:{}\'.format(test)

 有上面的图片可以看出来只要是前面匹配成功了,后面所有的包含\'/\'都会当做path。

endpoint

endpoint:反向生成url

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import url_for

app = Flask(__name__)


# 这里的endpoint我们可以不写,不写就默认为index和函数名一样
@app.route(\'/index/\', endpoint=\'first\')
def index():
    print(url_for(\'first\'))  # 如果上面没有穿endpoint得话就写\'index\'
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 

访问:http://127.0.0.1:5000/index/

pycharm控制台得到

/index/

 

这个不算是完整的url要想得到完整的url我们修改后为

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import url_for

app = Flask(__name__)


# 这里的endpoint我们可以不写,不写就默认为index和函数名一样
@app.route(\'/index/\', endpoint=\'first\')
def index():
    print(url_for(\'first\',_external=True))  # 如果上面没有穿endpoint得话就写\'index\'
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 

pycharm控制台输出为:

http://127.0.0.1:5000/index/

 

这样还是不够当我们后面有参数的时候怎么办

使用下面的方式:

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import url_for,request

app = Flask(__name__)


# 这里的endpoint我们可以不写,不写就默认为index和函数名一样
@app.route(\'/index/\', endpoint=\'first\')
def index():
    stu_id = int(request.args[\'id\'])
    print(url_for(\'first\', _external=True, id=stu_id))  # 如果上面没有穿endpoint得话就写\'index\'
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 

访问:http://127.0.0.1:5000/index/?id=1

pycharm控制台得到的输出为:

http://127.0.0.1:5000/index/?id=1

 

defaults

defaults : 视图函数的参数默认值{"nid":100}

注意:视图函数必须要设置形参nid,否则报错!

 

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import url_for,request

app = Flask(__name__)


# 这里的endpoint我们可以不写,不写就默认为index和函数名一样
@app.route(\'/index/\', endpoint=\'first\', defaults={\'nid\':100})
def index(nid):
    stu_id = int(request.args[\'id\'])
    print(url_for(\'first\', _external=True, id=stu_id))  # 如果上面没有穿endpoint得话就写\'index\'
    print(nid)
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 

访问:http://127.0.0.1:5000/index/?id=1

pycharm得到的结果为:

http://127.0.0.1:5000/index/?id=1
100

 

访问一个结尾不带斜线的url会被flask重定向到一个带斜线的规范url去,所以我们在写的时候还是要在路由后面加一个斜线

 

 

 响应

响应体 HttpResponse、Render、Redirect、jsonify

 HttpResponse

@app.route("/")  # app中的route装饰器
def index():  # 视图函数
    return "Hello World!"  # HttpResponse

在flask中的HttpResponse 其实就是直接返回字符串

 redirect

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import redirect

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


# url与视图映射
@app.route(\'/redi/\')
def redi():
    return redirect(\'/\')  # redirect跳转至"/"


@app.route(\'/\')
def index():
    return \'Hello Word!\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

在上面我们启动后访问:  http://127.0.0.1:5000/redi/

会看到Hello World

render

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import render_template  # 导入flask中的render_template

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)

@app.route(\'/index/\')
def index():
    return render_template(\'index.html\')


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

在当前的py文件的同级目录下创建一个templates目录然后在该目录下创建一个index.html文件

index.html内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

 我们可以重启后访问后会出现一下结果

 

 

在上面我们写return render_template(\'index.html\')

 会发现index.html这个飘黄我们可以在pycharm的右击templates -> Mark Directory as-->Template Folder

会跳出来一个选项选择yes就好,然后出来一个界面在右边有一个Tempalte language在后面我们选择Jinja2然后点击确定就好

 如果我们使用pycharm创建一个Flask项目就不会出现这个问题,但是现阶段建议自己手动操作,有利于更好的熟悉flask

jsonify

后端代码为

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import jsonify  # 导入flask中的jsonify

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


@app.route(\'/index/\')
def index():
    return jsonify({\'k1\':\'v1\'})


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

访问http://127.0.0.1:5000/index/

得到下图:

定制响应头。

flask如何给自己定制一个响应头信息

后端代码为

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import make_response  # make_response专门是用来设置响应头的

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


@app.route(\'/index/\')
def index():
    obj = make_response(\'qwer\')
    obj.headers[\'aaaa\'] = \'123\'
    obj.set_cookie(\'key\', \'value\')
    return obj


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 

访问:http://127.0.0.1:5000/index/

我们可以看到浏览器中信息

页面为:

点击右键选择 检查(使用的是Google Chrome)

 

 可以看到我们在上面设置的请求头在这里能够看到

再看看我们的cookie

这个就是我们定制的响应头

 

request相关

每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的

为了了解Flask的request中都有什么东西,首先我们要写一个前后端的交互

基于HTML + Flask 写一段前后端的交互

先写一段儿HTML form表单中提交方式是post  action地址是 /test

login.html的代码为

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>欢迎登陆</h1>
<form action="/test/" method="post">
    <p>
        <input type="text" name="user" placeholder="请输入用户名">
    </p>
    <p>
        <input type="password" name="pwd" placeholder="请输入密码">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

我们写的flask的代码为

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import render_template  # 导入flask中的render_template
from flask import request

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


@app.route(\'/login/\')
def index():
    return render_template(\'login.html\')


@app.route(\'/test/\')
def home():
    print(request)
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

我们访问http://127.0.0.1:5000/login/页面后随便输入用户名和密码或者直接提交就会出现下面的图示

这个提示是其请求的方式不被允许。

这个请求的方式不被允许是因为默认的路由只允许GET,我们提交的是POST所以这里不通过

request.methods

修改我们的flask代码

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import render_template  # 导入flask中的render_template
from flask import request

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


@app.route(\'/login/\')
def index():
    return render_template(\'login.html\')


@app.route(\'/test/\', methods=[\'POST\'])  # 表示只允许POST请求
def home():
    print(request)  # request对象
    print(request.method)
    print(request.form)
    print(request.form[\'user\'])
    print(request.form.get(\'pwd\'))
    print(request.form.keys())
    for i in request.form.keys():
        print(i)
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

 

重启后再次访问login然后输入用户名和密码都是admin,

控制台的输出为

<Request \'http://127.0.0.1:5000/test/\' [POST]>
POST
ImmutableMultiDict([(\'user\', \'admin\'), (\'pwd\', \'admin\')])
admin
admin
<dict_keyiterator object at 0x00000252AD6A0F48>
user
pwd

 

 上面的@app.route(\'/test/\', methods=[\'POST\'])

 后面的methods后面是列表,这个表示可以有多个值,所以我们想要允许什么的请求就在这里写上就好。

request.form

 上面我们Form表单提交的数据我们可以通过request.form拿到提交的数据。

print(request.form)  # ImmutableMultiDict([(\'user\', \'xiao\'), (\'pwd\', \'123\')])
# ImmutableMultiDict 它看起来像是的Dict 就用Dict的方法取值试一下吧
print(request.form["user"])  # admin
print(request.form.get("pwd"))  # admin
# 看来全部才对了, ImmutableMultiDict 似乎就是个字典,再来玩一玩它
print(list(request.form.keys()))  # [\'user\', \'pwd\'] 看来是又才对了
#如果以上所有的方法你都觉得用的不爽的话
req_dict = dict(request.form)
print(req_dict)  # 如果你觉得用字典更爽的话,也可以转成字典操作(这里有坑)

request.args

request.args中保存的是url中传递的参数

修改后端的GET

#!/usr/bin/env python
# -*-coding:utf-8-*-
from flask import Flask  # 导入Flask类
from flask import render_template  # 导入flask中的render_template
from flask import request

# 实例化一个Flask对象,传递__name__参数进去
app = Flask(__name__)


@app.route(\'/login/\')
def index():
    return render_template(\'login.html\')


@app.route(\'/test/\', methods=[\'POST\', \'GET\'])  # 表示只允许POST请求
def home():
    print(request.args)
    print(request.args[\'id\'])
    print(request.args.get(\'age\'))
    print(list(request.args.keys()))
    print(list(request.args.values()))
    req_dic = dict(request.args)
    print(req_dic)
    # print(request)  # request对象
    # print(request.method)
    # print(request.form)
    # print(request.form[\'user\'])
    # print(request.form.get(\'pwd\'))
    # print(request.form.keys())
    # for i in request.form.keys():
    #     print(i)
    return \'ok\'


if __name__ == \'__main__\':
    # 这里面的端口我们是可以自己设置的,我这里就没有设置了还是默认的5000
    # debug=True表示启动debug模式。当代码有改动时,Flask会自动加载,无序重启!默认是关闭的
    app.run(debug=True)  # 启动Flask服务

然后在url地址栏输入下面的url

http://127.0.0.1:5000/test/?id=13&age=28

得到如下页面

控制台我们得到的输出是

ImmutableMultiDict([(\'id\', \'13\'), (\'age\', \'28\')])
13
28
[\'id\', \'age\']
[\'13\', \'28\']
{\'id\': [\'13\'], \'age\': [\'28\']}

 有上面的示列可以看出request.form和request.args的区别

request.form是获取form表单中的参数

request.args是获取url中参数的

request.values

前端代码改动部位为黄色

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Flask之模板之宏继承包含

flask初识

python常用框架之一 Flask 初识Flask

初识python轻量web框架flask

Flask框架从入门到精通之初识

Python进阶(四十九)-初识Flask Blueprint