标准类视图
之前我们接触的视图都是函数,所以⼀般简称视图函数。其实视图也可以基于
类来实现,类视图的好处是⽀持继承,但是类视图不能跟函数视图⼀样,写完
类视图还需要通过app.add_url_rule(url_rule,view_func)来进⾏注册。
视图函数
@app.route('/profile/')
def profile():
return '个人中心'
类视图函数:
app.add_url_rule('/profile/',view_func=profile) view_func = 函数名称
他们的效果是一样的,打开网址
定义一个类,并且继承view类
from flask import Flask,views
class ListView(views.View): #####大写Viwe
def demo(self):
return '这是测试'
进入View查看源码
告诉我们必须重新写dispatch_request()方法不然就会报错上面我们没有重写dispatch_request()方法然后我们重新写一个路由
app.add_url_rule('/list/',view_func=ListView.as_view('list')) #list是别名
#as_view()有一个参数,参数是取得别名
我们打开网址果然报错了
我们重新写一个,并且重写dispatch_request()方法
class ListView(views.View):
def dispatch_request(self):
return '这是类视图的测试'
def demo(self):
return '这是测试'
打开网址
类视图有什么用呢,一般情况下,我们的类视图都是用来返回一个json数据(字典形式的一大串数据)类似于这种,前后还有好多数据
但是如果我们正常返回一个字典
class ListView(views.View):
def dispatch_request(self):
return {'username':'Zaaaacki'}
app.add_url_rule('/list/',view_func=ListView.as_view('list'))
他就是返回了一个字典,并不属于json,可能只是看起来像,但不是我们想要返回json数据怎么办呢首先我们导包jsonify
from flask import Flask,views,jsonify
然后我们重新创建一个类
class JsonView(views.View):
def get_response(self):
raise NotImplementedError()
def dispatch_request(self):
response = self.get_response()
return jsonify(response) #####返回json数据
重写get_response()方法继续创建一个类,并且继承JsonView
class ListJsonView(JsonView):
def get_response(self):
return {'username':'Zaaaacki'}
创建一个路由
app.add_url_rule('/listjson/',view_func=ListJsonView.as_view('listjson'))
打开网址
因为数据量比较少,看起来和我们返回一个字典一样,但是现在是json数据我们通过url_for打印一下路由如果我们访问这个
我们通常的做法是把这个名称,放到url_for后面但是通过类试图函数,我们给ListJsonView取了别名所以我们通过url_for打印路由的时候,我们应该用他的别名,不然是会报错的
@app.route('/')
def index():
print(url_for('listjson'))
return '首页'
endpoint参数有什么用呢,也是取别名我们先看一下,我们在刚才的函数中传递了endpoint参数
app.add_url_rule('/listjson/',endpoint='listjson1',view_func=ListJsonView.as_view('listjson'))
前面的url_for()不做修改,打开网址
哎嘿?报错了我们把url_for后面的参数改为endpoint后面的参数试试
@app.route('/')
def index():
print(url_for('listjson1'))
return '首页'
打开网址
这回就成功了
这说明endpoint,和as_view同时存在时,会使用endpoint后面的别名
标准类试图的使用
我们想要创建两个页面一个登陆页面,一个注册页面我们定义两个类 LoginView和RegistView,分别写入登陆页面的模板和注册页面的模板
#登陆
class LoginView(views.View):
def dispatch_request(self):
self.context = {
'username':'Zaaaacki'
}
return render_template('login.html',**self.context)
#注册
class RegistView(views.View):
def dispatch_request(self):
self.context = {
'username':'Zaaaacki'
}
return render_template('regist.html',**self.context)
这两个部分重复
我已我们在创建一个初始化类,让前面两个类继承
class BaseView(views.View):
def __init__(self):
self.context = {
'username': 'Zaaaacki'
}
#登陆
class LoginView(BaseView):
def dispatch_request(self):
return render_template('login.html',**self.context)
#注册
class RegistView(BaseView):
def dispatch_request(self):
return render_template('regist.html',**self.context)
完整的代码
from flask import Flask,views,render_template
app = Flask(__name__)
@app.route('/')
def index():
return '首页'
class BaseView(views.View):
def __init__(self):
self.context = {
'username': 'Zaaaacki'
}
#登陆
class LoginView(BaseView):
def dispatch_request(self):
return render_template('login.html',**self.context)
#注册
class RegistView(BaseView):
def dispatch_request(self):
return render_template('regist.html',**self.context)
app.add_url_rule('/login/',view_func=LoginView.as_view('login'))
app.add_url_rule('/regist/',view_func=RegistView.as_view('regist'))
if __name__ =='__main__':
app.run(debug=True)
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>这是登陆页面</h1>
<p>{{username}}</p>
</body>
</html>
regist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>这是注册页面</h1>
<p>{{username}}</p>
</body>
</html>
打开网址