Flask框架

Posted by Andy on September 6, 2023

参考链接:
flask框架
Python Flask Web 框架入门
Flask全套知识点从入门到精通,学完可直接做项目

hello world

1
2
3
4
5
6
7
8
9
10
from flask import Flask
 
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    return 'Hello World!'
 
if __name__ == '__main__':
    app.run()

获取URL参数

列出所有参数

server:

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask, request
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    return request.args.__str__()
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

http://127.0.0.1:5000/?user=Flask&time&p=7&p=8 输出:

1
ImmutableMultiDict([('user', 'Flask'), ('time', ''), ('p', '7'), ('p', '8')])

较新的浏览器也支持直接在url中输入中文(最新的火狐浏览器内部会帮忙将中文转换成符合URL规范的数据),在浏览器中访问http://127.0.0.1:5000/?info=这是爱

输出:

1
ImmutableMultiDict([('info', '这是爱,')])

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask, request
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    print(request.path)
    print(request.full_path)
    return request.args.__str__()
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

http://127.0.0.1:5000/?info=这是爱 输出:

1
2
/
/?info=%E8%BF%99%E6%98%AF%E7%88%B1%EF%BC%8C

获取指定参数

server:

1
2
3
4
5
6
7
8
9
10
from flask import Flask, request
 
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    return request.args.get('info')
 
if __name__ == '__main__':
    app.run(port=5000)

http://127.0.0.1:5000/?info=hello 输出:

1
helo

在URL参数中找到info。所以request.args.get(‘info’)返回Python内置的None,而Flask不允许返回None

server设置默认值:

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask, request
 
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    r = request.args.get('info', 'hi')
    return r
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

http://127.0.0.1:5000/ 输出:

1
hi

处理多值

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask, request
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    r = request.args.getlist('p')  # 返回一个list
    return str(r)
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

http://127.0.0.1:5000/?user=Flask&time&p=7&p=8 输出:

1
['7', '8']

将python的参数传入到前端模版

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask,render_template

app=Flask(__name__)

@app.route('/about')
def about():
    context={
        "username": "李四"
    }
    return render_template("about.html", **context)  # **context 传递字典

if __name__ == '__main__':
    app.run(debug=True)

about_html:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们</title>
</head>
<body>
    <h1>我们是最棒的。</h1>
</body>
</html>

获取POST方法传送的数据

查看数据内容

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from flask import Flask, request
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/register', methods=['POST','GET']) #同时接受POST和GET方法
def register():
    print(request.headers)
    print(request.stream.read())
    return 'welcome'
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

client:

1
2
3
4
5
6
import requests
 
user_info = {'name': 'letian', 'password': '123'}
r = requests.post("http://127.0.0.1:5000/register", data=user_info)
 
print(r.text)

输出:

1
welcome

控制台输出:

1
2
3
4
5
6
7
8
9
Host: 127.0.0.1:5000
User-Agent: python-requests/2.19.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 24
Content-Type: application/x-www-form-urlencoded

b'name=letian&password=123'

解析POST数据

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from flask import Flask, request
 
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/register', methods=['POST'])
def register():
    print(request.headers)
    # print(request.stream.read()) # 不要用,否则下面的form取不到数据
    print(request.form)
    print(request.form['name'])
    print(request.form.get('name'))
    print(request.form.getlist('name'))
    print(request.form.get('nickname', default='little apple'))
    return 'welcome'
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

控制台输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Host: 127.0.0.1:5000
User-Agent: python-requests/2.19.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 24
Content-Type: application/x-www-form-urlencoded
 
 
ImmutableMultiDict([('name', 'letian'), ('password', '123')])
letian
letian
['letian']
little apple

equest.form会自动解析数据。 request.form[‘name’]和request.form.get(‘name’)都可以获取name对应的值。对于request.form.get()可以为参数default指定值以作为默认值

1
print(request.form.get('nickname', default='little apple'))

输出默认值

1
little apple

cilent:

1
2
3
4
5
6
import requests
 
user_info = {'name': ['letian', 'letian2'], 'password': '123'}
r = requests.post("http://127.0.0.1:5000/register", data=user_info)
 
print(r.text)

print(request.form.getlist(‘name’))输出:

1
[u'letian', u'letian2']

处理响应JS数据

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from flask import Flask, request
 
app = Flask("my-app")
 
 
@app.route('/')
def hello_world():
    return 'Hello World!'
 
 
@app.route('/add', methods=['POST'])
def add():
    print(request.headers)
    print(type(request.json))
    print(request.json)
    result = request.json['a'] + request.json['b']
    return str(result)
 
 
if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000, debug=True)

client:

1
2
3
4
5
6
7
import requests
 
json_data = {'a': 1, 'b': 2}
 
r = requests.post("http://127.0.0.1:5000/add", json=json_data)
 
print(r.text)

client输出:

1
3

server输出:

1
2
3
4
5
6
7
8
9
10
11
Host: 127.0.0.1:5000
User-Agent: python-requests/2.19.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 16
Content-Type: application/json
 
 
<class 'dict'>
{'a': 1, 'b': 2}

响应JSON时,除了要把响应体改成JSON格式,响应头的Content-Type也要设置为application/json

响应JSON数据方案1

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from flask import Flask, request, Response
import json
 
app = Flask("my-app")
 
 
@app.route('/')
def hello_world():
    return 'Hello World!'
 
 
@app.route('/add', methods=['POST'])
def add():
    result = {'sum': request.json['a'] + request.json['b']}
    return Response(json.dumps(result),  mimetype='application/json')
 
 
if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000, debug=True)

client:

1
2
3
4
5
6
7
8
import requests
 
json_data = {'a': 1, 'b': 2}
 
r = requests.post("http://127.0.0.1:5000/add", json=json_data)
 
print(r.headers)
print(r.text)

client输出:

1
2
{'Content-Type': 'application/json', 'Content-Length': '13', 'Server': 'Werkzeug/0.14.1 Python/3.6.5', 'Date': 'Thu, 06 Sep 2018 08:59:59 GMT'}
{"sum":3}

另外,如果需要服务器的HTTP响应头具有更好的可定制性,比如自定义Server,可以如下修改add()函数

1
2
3
4
5
6
@app.route('/add', methods=['POST'])
def add():
    result = {'sum': request.json['a'] + request.json['b']}
    resp = Response(json.dumps(result),  mimetype='application/json')
    resp.headers.add('Server', 'python flask')
    return resp

client将输出:

1
2
{'Content-Type': 'application/json', 'Content-Length': '10', 'Server': 'python flask', 'Date': 'Sat, 07 Jul 2018 05:26:40 GMT'}
{"sum": 3}

响应JSON数据方案2

使用 jsonify 工具函数即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, request, jsonify
 
app = Flask("my-app")
 
 
@app.route('/')
def hello_world():
    return 'Hello World!'
 
 
@app.route('/add', methods=['POST'])
def add():
    result = {'sum': request.json['a'] + request.json['b']}
    return jsonify(result)
 
 
if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000, debug=True)

上传文件

使用POST方法

server code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from flask import Flask, request
 
from werkzeug.utils import secure_filename
import os
 
app = Flask(__name__)
  
# 文件上传的大小  
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 #16MB
# 文件上传目录
app.config['UPLOAD_FOLDER'] = 'static/'
# 支持的文件格式
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'}  # 集合类型
 
 
# 判断文件名是否是我们支持的格式
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
 
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/upload', methods=['POST'])
def upload():
    upload_file = request.files['image']
    if upload_file and allowed_file(upload_file.filename):
        filename = secure_filename(upload_file.filename)
        # 将文件保存到 static/uploads 目录,文件名同上传时使用的文件名
        upload_file.save(os.path.join(app.root_path, app.config['UPLOAD_FOLDER'], filename))
        return 'info is '+request.form.get('info', '')+'. success'
    else:
        return 'failed'
 
 
if __name__ == '__main__':
    app.run(debug=True)

upload_file.save(path)用来将upload_file保存在服务器的文件系统中,参数最好是绝对路径,否则会报错

clint code

1
2
3
4
5
6
7
8
9
import requests
 
file_data = {'image': open('Andy.jpg', 'rb')}
 
user_info = {'info': 'Andy'}
 
r = requests.post("http://127.0.0.1:5000/upload", data=user_info, files=file_data)
 
print(r.text)

编码转换

server code

1
2
3
4
5
6
7
8
9
10
11
12
@app.route('/user/<username>')
def user(username):
    print(username)
    print(type(username))
    return 'hello ' + username
 
 
@app.route('/user/<username>/friends')
def user_friends(username):
    print(username)
    print(type(username))
    return 'hello ' + username

http://127.0.0.1:5000/user/andy http://127.0.0.1:5000/user/andy/friends 输出:

1
2
andy
<class 'str'>
  • 加入类型转换器:
    1
    2
    3
    4
    5
    
    @app.route('/page/<int:num>')
    def page(num):
      print(num)
      print(type(num))
      return 'hello world'
    

http://127.0.0.1:5000/page/1 输出:

1
2
1
<class 'int'>
  • 3个默认转换器
    1
    2
    3
    
    int     accepts integers
    float     like int but for floating point values
    path     like the default but also accepts slashes
    

server code

1
2
3
4
5
@app.route('/page/<int:num1>-<int:num2>')
def page(num1, num2):
    print(num1)
    print(num2)
    return 'hello world'

http://127.0.0.1:5000/page/11-22 输出:

1
2
11
22

url_for生成链接

server code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from flask import Flask, url_for

app = Flask(__name__)


@app.route('/')
def hello_world():
    pass


@app.route('/user/<name>')
def user(name):
    pass


@app.route('/page/<int:num>')
def page(num):
    pass


@app.route('/test')
def test():
    print(url_for('hello_world'))
    print(url_for('user', name='Andy'))
    print(url_for('page', num=1, q='hadoop mapreduce 10%3'))
    print(url_for('static', filename='uploads/01.jpg'))
    return 'Hello'


if __name__ == '__main__':
    app.run(debug=True)

http://127.0.0.1:5000/test 输出:

1
2
3
4
/
/user/Andy
/page/1?q=hadoop+mapreduce+10%253
/static/uploads/01.jpg

redirect重定向

server code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from flask import Flask, url_for, redirect
 
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    return 'hello world'
 
@app.route('/test1')
def test1():
    print('this is test1')
    return redirect(url_for('test2'))
 
@app.route('/test2')
def test2():
    print('this is test2')
    return 'this is test2'
 
if __name__ == '__main__':
    app.run(debug=True)

http://127.0.01:5000/test1 输出:

1
this is test2

Jinja2模板

Jinja2是Flask默认的模板引擎,它是基于Python的模板引擎,它的语法和Django模板引擎的语法类似。Jinja2模板引擎的语法请见 http://docs.jinkan.org/docs/jinja2/ 。

Jinja2中的控制语句

所有的控制语句都是放在中,并且由来进行结束,Jinja中常用的控制语句有if和for…in…,下面我们来看一下这两个控制语句的用法。

server code

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route("/control")
def control():
    context={
        "age":17,
    }
    return render_template("control.html",**context)
if __name__ == '__main__':
    app.run(debug=True)

control_html:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制语句</title>
</head>
<body>

    <div>您刚成年!</div>

</body>
</html>

Jinja2模板过滤器

过滤器就是通过管道符( )进行使用的,例如就会返回name的长度,过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。

不想让books以列表的形式展现,想要books以字符串的形式显示,每个项用逗号进行分割,可以使用join过滤器去处理

server code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route('/about')
def about():
    context={
        "username":"lisi",
        "books":["红楼梦","西游记"]
    }
    return render_template("about.html",**context)

if __name__ == '__main__':
    app.run(debug=True)

about_html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们</title>
</head>
<body>
    <h1>我们是最棒的。</h1>
    <h1></h1>
    <h1></h1>
</body>
</html>

输出:

1
2
3
我们是最棒的。4
['红楼梦','西游记']
红楼梦,西游记

将python的变量传入前端模板

server code

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route('/about')
def about():
    context={
        "username":"李四"
    }
    return render_template("about.html",**context)

if __name__ == '__main__':
    app.run(debug=True)

模版

模版继承

Flask中的模板可以继承,通过继承可以把模板中许多重复出现的元素抽取出来,放在父模板中,并且父模板通过定义block给子模板开一个口,子模板根据需要,再实现这个block,这样就可以实现模板的复用。

app_py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'hello world'


@app.route('/user')
def user():
    user_info = {
        'name': 'Andy',
        'email': '123@aa.com',
        'age': 21,
        'github': 'https://github.com/andy-boy123'
    }
    return render_template('user_info.html', page_title='Andy\'s info', user_info=user_info)


if __name__ == '__main__':
    app.run(port=5000, debug=True)

http://127.0.0.1:5000/user

网页源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
    <title>
        Andy's info
    </title>
</head>
<body>
    name: Andy 
    email:123@aa.com
    age: 21
    github:https://github.com/andy-boy123
</body>
</html>

自定义404等页面

401未登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, render_template_string, abort
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/user')
def user():
    abort(401)  # Unauthorized 未授权
    print('Unauthorized, 请先登录')
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from flask import Flask, render_template_string, abort
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/user')
def user():
    abort(401)  # Unauthorized
 
 
@app.errorhandler(401)
def page_unauthorized(error):
    return render_template_string('<h1> Unauthorized </h1><h2></h2>', error_info=error), 401
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

page_unauthorized函数返回的是一个元组,401 代表HTTP 响应状态码。如果省略401,则响应状态码会变成默认的 200。

用户会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from flask import Flask, render_template_string, \
    session, request, redirect, url_for
 
app = Flask(__name__)
 
app.secret_key = 'F12Zr47j\3yX R~X@H!jLwf/T'
 
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/login')
def login():
    page = '''
    <form action="" method="post">
        <p>name: <input type="text" name="user_name" /></p>
        <input type="submit" value="Submit" />
    </form>
    '''
    return render_template_string(page)
 
 
@app.route('/do_login', methods=['POST'])
def do_login():
    name = request.form.get('user_name')
    session['user_name'] = name
    return 'success'
 
 
@app.route('/show')
def show():
    return session['user_name']
 
 
@app.route('/logout')
def logout():
    session.pop('user_name', None)
    return redirect(url_for('login'))
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

app.secret_key用于给session加密。

在/login中将向用户展示一个表单,要求输入一个名字,submit后将数据以post的方式传递给/do_login,/do_login将名字存放在session中。

如果用户成功登录,访问/show时会显示用户的名字。此时,打开firebug等调试工具,选择session面板,会看到有一个cookie的名称为session。

/logout用于登出,通过将session中的user_name字段pop即可。Flask中的session基于字典类型实现,调用pop方法时会返回pop的键对应的值;如果要pop的键并不存在,那么返回值是pop()的第二个参数。

另外,使用redirect()重定向时,一定要在前面加上return。

进入http://127.0.0.1:5000/login,输入name,点击submit:

进入http://127.0.0.1:5000/show查看session中存储的name:

设置session的过期时间:

1
2
3
4
5
from datetime import timedelta
from flask import session, app
 
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=5)

使用cookie

Cookie是存储在客户端的记录访问者状态的数据。具体原理,请见 http://zh.wikipedia.org/wiki/Cookie 。 常用的用于记录用户登录状态的session大多是基于cookie实现的。

cookie可以借助flask.Response来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from flask import Flask, request, Response, make_response
import time
 
app = Flask(__name__)
 
 
@app.route('/')
def hello_world():
    return 'hello world'
 
 
@app.route('/add')
def login():
    res = Response('add cookies')
    res.set_cookie(key='name', value='1234', expires=time.time()+6*60)
    return res
 
 
@app.route('/show')
def show():
    return request.cookies.__str__()
 
 
@app.route('/del')
def del_cookie():
    res = Response('delete cookies')
    res.set_cookie('name', '', expires=0)
    return res
 
 
if __name__ == '__main__':
    app.run(port=5000, debug=True)

可以使用Response.set_cookie添加和删除cookie。expires参数用来设置cookie有效时间,它的值可以是datetime对象或者unix时间戳,此处使用的是unix时间戳

1
res.set_cookie(key='name', value='letian', expires=time.time()+6*60)

expire参数值表示cookie在6分钟后过期。 要删除cookie,只需要将expires设置为0即可

1
res.set_cookie('name', '', expires=0)

闪存系统 flashing system

闪存系统是一种临时存储数据的机制,它可以在一次请求中存储信息,然后在另一次请求中读取信息。闪存系统是基于session实现的,它的原理是将数据存储在session中,然后在下一次请求中将数据从session中删除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from flask import Flask, flash, get_flashed_messages
import time
 
app = Flask(__name__)
app.secret_key = 'some_secret'
 
 
@app.route('/')
def index():
    return 'hi'
 
 
@app.route('/gen')
def gen():
    info = 'access at '+ time.time().__str__()
    flash(info)
    return info
 
 
@app.route('/show1')
def show1():
    return get_flashed_messages().__str__()
 
 
@app.route('/show2')
def show2():
    return get_flashed_messages().__str__()
 
 
if __name__ == "__main__":
    app.run(port=5000, debug=True)

打开浏览器,访问http://127.0.0.1:5000/gen

1
access at 1694068052.5214832

打开浏览器,访问http://127.0.0.1:5000/gen

1
access at 1694068064.4610322

使用浏览器访问http://127.0.0.1:5000/show1

1
['access at 1694068052.5214832', 'access at 1694068064.4610322']

http://127.0.0.1:5000/show2

1
[]

flash分类(category):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from flask import Flask, flash, get_flashed_messages
import time

app = Flask(__name__)

app.secret_key = 'some_secret'


@app.route('/')
def index():
    return 'hi'
 
 
@app.route('/gen')
def gen():
    info = 'access at '+ time.time().__str__()  #获取当前时间
    flash('show1 '+info, category='show1')    #分类1
    flash('show2 '+info, category='show2')    #分类2
    return info
 
#只显示分类1
@app.route('/show1')
def show1():
    return get_flashed_messages(category_filter='show1').__str__()
 
#只显示分类2
@app.route('/show2')
def show2():
    return get_flashed_messages(category_filter='show2').__str__()
 
 
if __name__ == "__main__":
    app.run(port=5000, debug=True)

蓝图和子域名

之前我们写的url和视图函数都是处在同一个文件,如果项目比较大的话,这显然不是一个合理的结构,而蓝图可以帮助我们实现这种需求。功能是将项目模块划分。

先写三个子模块,这三个文件全放在apps这个python packages里,结构如下

  • Flask
    • apps
      • init_py
      • book_py
      • course_py
      • user_py

init_py:

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask
from apps.book import bp as book_bp
from apps.course import bp as course_bp
from apps.user import bp as user_bp
app=Flask(__name__)
app.register_blueprint(book_bp)
app.register_blueprint(course_bp)
app.register_blueprint(user_bp)

if __name__ == '__main__':
    app.run(debug=True)

book_py:

1
2
3
4
5
6
from flask import Blueprint
# url_prefix就是设置url前缀
bp = Blueprint("book", __name__, url_prefix="/book")
@bp.route("/list")
def book_list():
    return "图书列表"

course_py:

1
2
3
4
5
6
from flask import Blueprint
# url_prefix就是设置url前缀
bp = Blueprint("course", __name__, url_prefix="/course")
@bp.route("/list")
def course_list():
    return "课程列表"

user_py:

1
2
3
4
5
6
from flask import Blueprint
# url_prefix就是设置url前缀
bp = Blueprint("user", __name__, url_prefix="/user")
@bp.route("/list")
def user_list():
    return "用户列表"

访问http://127.0.0.1:5000/book/list 显示:

1
图书列表

其他也类似