20標準類視圖、基於調度方法的類視圖、使用裝飾器的類視圖

 一:標準類視圖:https://www.bilibili.com/video/av62010252/?p=36html

1, 標準類視圖:必須繼承自 views.View(from flask import Flask,views)json

2,必須實現dispatch_request(self)方法,之後請求過來後,都會執行這個方法,這個方法的返回值就至關因而以前的函數視圖同樣。也必須返回「」Response「。」flask

3,必須經過app

「app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))」ide

來作URL與類視圖的映射,‘’view_func‘’這個參數,須要使用類視圖下的「as_view」類方法轉換:函數

4,若是指定了endpoint,那麼使用url_for時候就必須使用它。若是沒有指定,那麼默認爲類視圖名字。post

代碼示例:ui

 1 from flask import Flask,views
 2 
 3 app = Flask(__name__)
 4 
 5 class ListView(views.View):
 6     def dispatch_request(self):
 7         return "list view"
 8 
 9 app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))
10 
11 
12 @app.route('/')
13 def hello_world():
14     return 'Hello World!'
15 
16 
17 if __name__ == '__main__':
18     app.run()
 

 那麼,爲何咱們爲何有函數視圖還要用類視圖呢?首先,由於類比函數要功能多,封裝性也更強。封裝性在屢次調用時候體現。url

示例:spa

加入有幾個URL須要返回json數據,那麼:

 1 from flask import Flask,views,jsonify,render_template
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 #加入有幾個URL須要返回json數據
 7 class JsonView(views.View):
 8     def get_data(self):
 9         raise NotImplementedError
10     def dispatch_request(self):
11         return jsonify(self.get_data())
12 
13 class ListView(JsonView):
14     def get_data(self):
15         return {'username':'zy','password':'123'}
16 app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))
17 
18 
19 #有幾個視圖,須要返回相同的變量
20 class ADSView(views.View):
21     def __init__(self):
22         super(ADSView, self).__init__()
23         self.content = {
24             'ads':'This is ads!'
25         }
26 
27 class LoginView(ADSView):
28     def dispatch_request(self):
29         self.content.update({
30             'user': 'zy'
31         })
32         return render_template('login.html',**self.content)
33 
34 class RegistView(ADSView):
35     def dispatch_request(self):
36         return render_template('regist.html',**self.content)
37 app.add_url_rule('/login/',view_func=LoginView.as_view('login'))
38 app.add_url_rule('/regist/',view_func=RegistView.as_view('regist'))
39 
40 
41 @app.route('/')
42 def hello_world():
43     return 'Hello World!'
44 
45 
46 if __name__ == '__main__':
47     app.run()

詳細解釋:
行16中URL輸入http://127.0.0.1:5000/list/時,視圖函數會調用類視圖ListView,而類視圖中必需要有dispatch_request(self),但是這個ListView是子視圖,沒有這個函數,
這時候須要調用上層的父類JsonView,由其調用dispatch_request(self)函數,執行jsonify(self.get_data())代碼,由於是子類調用它,因此這個jsonify(self.get_data())
中的self就爲子類自己,即調用子類中的get_data()函數。
那麼爲何父類中還有get_data函數呢,它也沒啥用?因
爲JsonView是不能直接用的,他只是一個抽象的,並不能當作實際視圖來用,因此他下面的get_data也不能用,所以用raise。
 
login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登錄頁面廣告</h1>
{{ ads }} === {{ user }}
</body>
</html>

 

 

類視圖有如下好處:

能夠繼承,把一些共性的東西抽取出來放在父視圖中,子視圖直接拿來用就能夠了,與函數視圖對比那個方便就用哪一個。

 

二,基於調度方法的類視圖 https://www.bilibili.com/video/av62010252/?p=36

先貼一段代碼:

 1 from flask import Flask,views,render_template,request
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/')
 7 def hello_world():
 8     return 'Hello World!'
 9 
10 class LoginView(views.MethodView):
11     def get(self):
12         return render_template('login.html')
13     def post(self):
14         username = request.form.get('name')
15         if username == 'zy':
16             return 'Login success'
17         else:
18             return 'faied'
19 
20 app.add_url_rule('/login/',endpoint='login',view_func=LoginView.as_view('list'))
21 
22 if __name__ == '__main__':
23     app.run()

注意:基於調度方法的類視圖是MethodView,而非View。

若是咱們要加上錯誤後的提示信息應該怎麼加呢?

 1 from flask import Flask,views,render_template,request
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/')
 7 def hello_world():
 8     return 'Hello World!'
 9 
10 class LoginView(views.MethodView):
11  def __geterror(self,error): 12         return render_template('login.html',error=error) 13     def get(self):
14         return render_template('login.html')
15     def post(self):
16         username = request.form.get('name')
17         if username == 'zy':
18             return 'Login success'
19         else:
20             return self.__geterror(error='密碼或帳戶錯誤')
21 
22 app.add_url_rule('/login/',endpoint='login',view_func=LoginView.as_view('list'))
23 
24 if __name__ == '__main__':
25     app.run()

三,使用裝飾器的類視圖 

普通使用裝飾器的函數視圖,代碼:

 1 from flask import Flask,request,render_template
 2 from functools import wraps
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/')
 7 def hello_world():
 8     return 'Hello World!'
 9 
10 def login_required(func):
11     @wraps(func)   #這裏爲何要加這個呢?由於爲了防止func函數的屬性丟失。 12     def wrapper(*args,**kwargs):
13         user = request.args.get('user')
14         #這裏是arg,因此應該寫爲/set/?user=zy
15         if user and user == 'zy':
16             return func(*args,**kwargs)
17         else:
18             return '請先登陸'
19     return wrapper
20 
21 @app.route('/set/')
22 @login_required
23 def set():
24     return '這裏是設置界面'
25 
26 
27 
28 
29 if __name__ == '__main__':
30     app.run()

那麼使用裝飾器的類方法的實現怎麼弄呢?

 1 from flask import Flask,request,render_template
 2 from functools import wraps
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/')
 7 def hello_world():
 8     return 'Hello World!'
 9 
10 def login_required(func):
11     @wraps(func)   #這裏爲何要加這個呢?由於爲了防止func函數的屬性丟失。
12     def wrapper(*args,**kwargs):
13         user = request.args.get('user')
14         #這裏是arg,因此應該寫爲/set/?user=zy
15         if user and user == 'zy':
16             return func(*args,**kwargs)
17         else:
18             return '請先登陸'
19     return wrapper
20 
21 @app.route('/set/')
22 @login_required
23 def set():
24     return '這裏是設置界面'
25 
26 from  flask import views
27 class ProfileView(views.View):
28     decorators = [login_required]  #直接這樣就好了,不用打括號 29     def dispatch_request(self):
30         return '這裏是設置界面'
31 app.add_url_rule('/pro/',endpoint='profile',view_func=ProfileView.as_view('profile'))
32 
33 
34 
35 
36 
37 if __name__ == '__main__':
38     app.run()
相關文章
相關標籤/搜索