4.Flask:视图函数

Flask(视图函数 四)

基于类的视图,可插拔视图

从Django学来的

好处:

  1. 类可以继承
  2. 代码可以复用
  3. 可以定义多种行为
    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
    from flask import Flask, request
    from flask.views import View

    app = Flask(__name__)


    class UserView(View):
    methods = ['GET', 'POST']

    def get(self):
    return 'get'

    def post(self):
    return 'post'

    # 分配请求
    def dispatch_request(self):
    dispatch_pattern = {'GET': self.get, 'POST': self.post}
    method = request.method
    return dispatch_pattern.get(method)()


    app.add_url_rule(
    '/user',
    view_func=UserView.as_view('user'),
    methods=["GET", "POST"]
    )

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

GET

装饰这个类视图

由于会被as_view转换,所以需要显式的装饰它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def log_time(f):
def decorator(*args, **kwargs):
print(time.time())
return f(*args, **kwargs)

return decorator


f = UserView.as_view('user')
log_time(f)

app.add_url_rule(
'/user',
view_func=f,
methods=["GET", "POST"]
)

使用MethodView

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, request
from flask.views import View, MethodView

app = Flask(__name__)


class ProjectView(MethodView):
def get(self):
return 'get'

def post(self):
return 'post'


app.add_url_rule(
'/project',
view_func=ProjectView.as_view('project'),
methods=["GET", "POST"]
)

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

这个类就是继承了View然后重写了dispatch_request

1
2
3
4
5
6
7
8
9
10
def dispatch_request(self, *args, **kwargs):
meth = getattr(self, request.method.lower(), None)

# If the request method is HEAD and we don't have a handler for it
# retry with GET.
if meth is None and request.method == "HEAD":
meth = getattr(self, "get", None)

assert meth is not None, "Unimplemented method %r" % request.method
return meth(*args, **kwargs)

相当于

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MethodView:
def get(self):
print('get')
return 'get'

def post(self):
print('post')
return 'post'

def dispatch_request(self):
func = getattr(self, 'get', None)
return func()


MethodView().dispatch_request()

func = getattr(self, 'get', None)

使用MethodView实现reful风格接口

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
from flask.views import MethodView
from flask import Flask

app = Flask(__name__)


class ProjectView(MethodView):
def get(self, project_id):
if project_id is None:
return 'ALL projects'
return f'get {project_id}'

def post(self, project_id):
return f'post {project_id}'

def put(self, project_id):
return f'put {project_id}'

def delete(self, project_id):
return f'delete {project_id}'


f = ProjectView.as_view('projects')
app.add_url_rule('/projects/<project_id>', view_func=f, methods=['GET', 'POST', 'PUT', 'DELETE'])
app.add_url_rule('/projects/', defaults={"project_id": None}, view_func=f, methods=['GET'])
if __name__ == '__main__':
app.run()

request获取请求数据

get

1
get_data = request.args

表单

1
form_data = request.form

json

1
json_data = request.json

file

1
file_data = request.files

上传文件的代码

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</title>
</head>
<body>
<form action="/uploads" method="post" enctype="multipart/form-data">
<input type="file" name="pic">
<input type="submit">
</form>
</body>
</html>

python代码

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
# -*- encoding: utf-8 -*-
"""
@File : homework.py
@Time : 2020/6/16 7:18 上午
@Author : zhongxin
@Email : 490336534@qq.com
"""
import os
import time

from flask import Flask, request, render_template, redirect

app = Flask(__name__)
print(app.instance_path)
print(app.root_path)
print(app.static_folder)


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


@app.route('/uploads', methods=['POST'])
def upload():
file = request.files.get('pic')
if not file:
return render_template('index.html')
file_name = time.strftime('%Y-%m-%d-%H-%M-%S') + file.filename
file_url = f'/static/{file_name}'
file.save(os.path.join(
app.root_path,
app.static_folder,
file_name
))
return redirect(file_url)


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

上传文件

 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
您的支持将鼓励我继续创作!