add_url_rule与app.route
add_url_rule与app.route都是flask为我们建立路由的方式,两者实现的功能是一样的。
add_url_rule的使用
首先是语法:
add_url_rule(rule,endpoint=None,view_func=None)
一共是三个参数:relu、endpoint、view_func,其中rule(path)、view_func是必须填写的参数。不填写endpoint则会默认使用view_func的名字作为endpoint。
from flask import Flask,url_for app = Flask(__name__) def show_me(): return '这是自我介绍!' # endpoint 中没有设置url_for 就写函数的名字,如果设置了就写endpoint app.add_url_rule('/show_me',view_func=show_me,endpoint='show') if __name__ == '__main__': app.run(debug=True)
在使用url_for 时,如果没有传递endpoint参数的时候,就使用view_func的名字,如果传递了endpoint参数,则应该使用endpoint指定的字符串。
@app.route
关于@app.route平时我们都是用这个吧,其底层原理其实就是使用的 add_url_rule ,对其进行了封装做成了装饰器,一样可以使用endpoint参数。
from flask import Flask,url_for app = Flask(__name__) @app.route('/',endpoint='index') # @app.route 底层就是使用的 add_url_rule ,对其进行了封装做成了装饰器。 def index(): print(url_for('index')) return 'hello' if __name__ == '__main__': app.run(debug=True)
类视图
优点:支持继承
缺点:写完类视图,还需要通过 add_url_rule 来进行注册。
标准类视图使用步骤
1. 标准类视图,必须继承自flask.views.View
2. 必须实现dispatch_request
方法。
3. 必须通过app.add_url_rule(rule,endpoint,view_func)
来做url与视图的映射。view_func
这个参数,需要使用类视图下的as_view
类方法类转换:ListView.as_view('list')
。
4. 如果指定了endpoint
,那么在使用url_for
反转的时候就必须使用endpoint
指定的那个值。如果没有指定endpoint
,那么就可以使用as_view(视图名字)
中指定的视图名字来作为反转。
from flask import Flask,url_for from flask.views import View app = Flask(__name__) class ListView(View): def dispatch_request(self): return '返回了一个List的内容。' app.add_url_rule('/List',view_func=ListView.as_view('mylist')) #用于测试 with app.test_request_context(): print(url_for('mylist')) if __name__ == '__main__': app.run(debug=True)
类视图的优点
前面也说,支持继承,可以把一些共性的东西提取出来放到父视图中去,子视图可以直接调用。但是并非所有视图都要用类视图,视图函数用的最多。
例:
from flask import Flask,jsonify from flask.views import View app = Flask(__name__) # 需求:返回的结果必须是json数据 class BaseView(View): def get_data(self): raise NotImplementedError def dispatch_request(self): return jsonify(self.get_data()) class JsonView(BaseView): def get_data(self): return {'uname':'xiaolin','age':20} class Json2View(BaseView): def get_data(self): return [ {'name':'xiaowang','age':19}, {'name':'xiaoyu','age':19}, ] app.add_url_rule('/base',view_func=BaseView.as_view('base')) app.add_url_rule('/json',view_func=JsonView.as_view('json')) app.add_url_rule('/json2',view_func=Json2View.as_view('json2')) if __name__ == '__main__': app.run(debug=True)
我们可以看到子视图jsonview和json2view继承了baseview,而baseview中已经重写了dispatch_request(),所以在继承后也不用再次重写该内容。
类视图的实战
在网页大部分登录页面和注册页面,只改变了一小部分东西,大部分的东西是共通的,页面上的内容基本上是相同的,但是却是两个不同的网页,这时候类视图的继承就会减轻了绝大部分的重复的代码。
py:
from flask import Flask,render_template from flask.views import View app = Flask(__name__) class BaseView(View): def __init__(self): self.msg = { 'main':'你好!!' } class LoginView(BaseView): def dispatch_request(self): my_msg = '登录功能' return render_template('login.html',msg = self.msg.get('main'),my_msg = my_msg) class RegisterView(BaseView): def dispatch_request(self): my_msg = '注册功能' return render_template('register.html',msg = self.msg.get('main'),my_msg = my_msg) app.add_url_rule('/login',view_func=LoginView.as_view('login')) app.add_url_rule('/register',view_func=RegisterView.as_view('register')) if __name__ == '__main__': app.run(debug=True)
login.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录页面</title> </head> <body> <h2>登录页面</h2> <table> <tr> <td>用户名:</td> <td><input type="text"></td> </tr> <tr> <td>密码:</td> <td><input type="password"></td> </tr> <tr> <td>登录</td> <td><input type="submit" , value="登录"></td> </tr> </table> <hr> 公共的内容:{{ msg }} <hr> 个人的内容:{{ my_msg }} </body> </html>
register.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>注册页面</title> </head> <body> <h2>注册页面</h2> <table> <tr> <td>用户名:</td> <td><input type="text"></td> </tr> <tr> <td>密码:</td> <td><input type="password"></td> </tr> <tr> <td>登录</td> <td><input type="submit" , value="登录"></td> </tr> </table> <hr> 公共的内容:{{ msg }} <hr> 个人的内容:{{ my_msg }} </body> </html>
效果图展示:
--------------------------------------------------------------------------------------------------------------------------------
End