add_url_rule与app.route都是flask为我们建立路由的方式,两者实现的功能是一样的。
首先是语法:
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平时我们都是用这个吧,其底层原理其实就是使用的 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:
登录页面
登录页面
用户名:
密码:
登录
公共的内容:{{ msg }}
个人的内容:{{ my_msg }}
register.html:
注册页面
注册页面
用户名:
密码:
登录
公共的内容:{{ msg }}
个人的内容:{{ my_msg }}
效果图展示:
--------------------------------------------------------------------------------------------------------------------------------
End