一:標準類視圖: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()