简介
本章主要涉及的知识点有:
- 路由函数app.route和add_url_rule函数的使用
- 标准视图函数的基本使用
- 基于方法的视图类的基本运用
- 装饰器的基本运用,以及代参数使用装饰器的方法
- 蓝图的作用定义和应用
app.route与add_url_rule简介
在flask应用之中,路由是指用户请求url与视图函数之间的映射,处理url之间的关系称之为映射,处理url和函数之间关系的程序成为路由。flask框架根据http请求的url在路由表中匹配的预定义的url规则,找到对应的视图函数,并将视图函数的执行结果返回给服务器。
app.route使用
在flask框架中,默认是使用@app.route装饰器
@app.route("/")
def hello world():
return 'hello world
使用app.route装饰器会将url和执行的是视图函数关系保存到app.url_map属性上,实现的是url与"/"与视图函数之间的绑定。
我们也可以通过url_for('hello_world')反转得到url''.
@app.route('/',endpoint='index')
def hello_world():
return 'hello world'
一旦我们使用endpoint参数,在使用url_for()反转时就不能使用视图函数名,而是已使用自定义的函数url名url_for('index')
add_url_rule的使用
我们还可以使用add_url_rule来绑定视图函数和url。add_url_rule(self,rule,endpoint=None,view_func=None,provide_automatic_options=None,**options)
* rule:设置url值
* endpoint:给url设置名称
* view_func:指定视图函数的名称
在上面代码中的endpoint只是指定了url名称,在view_func指定视图函数的名称
flask类视图
之前我们接触的视图都是函数,一般简称为视图函数,flask类的视图一般可以分为标准类的视图和基于掉度的方法的类视图。
标准类视图的特点:
- 必须继承flask.views.view
- 必须实现dispatch_request方法,也必须返回response或者是子类对象,或者是字符串、元组
- 必须通过app.add_url_rule(rule,endpoint,view_func)来做url与视图的映射,view_func参数需要使用as_view类方法转换
- 如果指定了endpoint,那么在使用url_for反转时必须使用endpoint指定的那个值。如果没有指定,那么可以使用as_view(视图名称)中指定视图函数名称来做为反转
app.py
from flask import Flask,render_template
app=Flask(__name__)#flask函数初始化
class Ads(views.View):#定义视图类Ads
def __init__(self):#实例化
super().__init__()#继承自__init__方法
self.context={ #设置
'ads':'这是对联广告'
}
#定义index类继承自Ads,和渲染模板
class Index(Ads):
def dispatch_request(self):
return render_template('index.html',**self.context)
class Login(Ads):
def dispatch_request(self):
return render_template('login.html',**self.context)
class Register(Ads):
def dispatch_request(self):
return render_template('register.html',**self.context)
#添加路由
app.add_url_rule(rule='/',endpoint='index',view_func=Index.as_view('Index'))
app.add_url_rule(rule='/login/',endpoint='login',view_func=Index.as_view('login'))
app.add_url_rule(rule='/register/',endpoint='register',view_func=Index.as_view('register'))
#运行
if __name__=='__main__':
app.run(debug=Ture)
注意:__init__方法第一个参数永远是self,表示创建的实例的本身
基于方法类的视图
flask提供一种另一种类视图flask.views.MethonView,对每个http方法执行不同的函数(映射到对应方法的小写同名方法上)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
.div1 {
height: 180px;
width: 380px;
border: 1px solid #8A8989;
margin: 0 auto;
}
.input {
display: block;
width: 350px;
height: 40px;
margin: 10px auto;
}
.button{
background: #2066c5;
color: white;
font-size: 18px;
font-weight: bold;
height: 50px;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="div1">< action="login" method="post"><form>
<input type="text" class="input" name="username" placeholder="请输入用户名">
<input type="text" class="input" name="password" placeholder="密码">
<input type="submit" value="登录" class="input button">
</form>></div>
</body>
</html>
flask装饰器
装饰器的本质是一个python函数,它可以让其他函数在不需要任何代码变动的前提下,增加额外的功能,装饰器的返回值是一个人函数对象。
from flask import Flask#导入flask模块
app=Flask(__name__)#flask框架初始化
@app.route('/')#定义路由器
def hello_world():#定义视图函数
return "hello world"#返回值
def user_login(func):#定义函数使func()接收作为参数
def inner():#定义inner()函数
print('登录操作')
func()#执行func函数
return inner
def news():#定义函数news()
print('这是新闻的详情页')
show_news=user_login(news)#将new作为参数传递给user_login()函数
shows_news()#执行
print(show_news.__name__)
if __name__ =='__main__':
app.run()
对带参数的函数使用装饰器
1.函数的可变参数
def func():
*:代表元组,长度不限
**:代表键值对
*args:代表元组,长度不限
**kwargs:代表键值对,个数不限
2.对参数使用装饰器
from flask import Flask#导入flask模块
app=Flask(__name__)#flask框架初始化
@app.route('/')#定义路由器
def hello_world():#定义视图函数
return "hello world"#返回值
def user_login(func):#定义函数使func()接收作为参数
def inner(*args,**kwargs):#定义inner()函数
print('登录操作')
func(*args,**kwargs)#执行func函数
return inner
@user_login
def news():
print(news.__name__)
print('这是详情页')
news();
@user_login
def news_list(*args):
page=args[0]
print('这是新闻列表第'+str(page)+'页')
news_list(5)
if __name__ =='__main__':
app.run()
蓝图
蓝图的定义:在蓝图被注册到应用之后,所要执行的操作的集合。当分配请求时,flask把蓝图和视图函数关联起来,并生成俩端之前的url。
蓝图可以极大的简化大型应用,并为拓展提供集中的注册入口。
蓝图的目的是实现各个模块的视图函数卸载不同的py文件中,在主视图中导入分路,有视图模块,并且注册蓝图对象。
注意:视图函数和蓝图名称不能一样
from flask import Flask#导入flask模块
app=Flask(__name__)#flask框架初始化
@app.route('/')#定义路由器
def hello_world():#定义视图函数
return "hello world"#返回值
app.register_blueprint(new.new_list)#将news模块里的蓝图对象new_list注册到app
app.register_blueprint(product.product_list)#将product模块里的蓝图product_list注册到app
if __name__=='__main__':
app.run(debug=True)
news.py
from flask import Blueprint #导入模块
new_list=Blueprint('news,__name__')#创建一个Blueprint对象。第一个参数可以看做该Blueprint对象的名字
#在一个app里,姓名不能与其余的Blueprint姓名重复
#在第二个参数__name__用作初始化
@new_list.route("/news")#将蓝图对象当做app一样使用
def new():#定义函数news()
return "这是新闻模块的"
product.py
from flask import Blueprint #导入模块
new_list=Blueprint('product,__name__')#创建一个Blueprint对象。第一个参数可以看做该Blueprint对象的名字
#在一个app里,姓名不能与其余的Blueprint姓名重复
#在第二个参数__name__用作初始化
@new_list.route("/product")#将蓝图对象当做app一样使用
def product():#定义函数product()
return "这是产品模块"