类视图

Flask 学习笔记

一、视图函数


        之前我们接触的视图都是函数,所以一般简称 “视图函数”。视图函数除了可以通过 @app.route("") 装饰器进行 url 映射外,还可以通过 app.add_url_rule(url_rule, view_func) 进行映射。

	def login():
	    # 如果 add_url_rule 设了参数 endpoint, 相当于给 URL 起了一个别名
	    # 可以通过别名, 反转获取 url(endpoint 优先级比 view_func 高)
	    # print(url_for("lg"))
	    print(url_for("login"))
	    return "不使用 @app.route("") 装饰器进行渲染"
	
	
	# app.add_url_rule('/login/', endpoint='lg', view_func=login)
	app.add_url_rule('/login/', view_func=login)



二、类视图


2.1、标准类视图

        其实视图也可以基于类来实现,类视图的好处是支持继承。标准类视图是继承自 flask.views.View,并且在子类中必须重写 dispatch_request 方法,因为它会主动抛出异常(详情看源码)。这个方法类似于视图函数,也要通过 app.add_url_rule(url_rule,view_func) 来进行注册,返回一个基于 Response 或者其子类的对象。

	from flask import views
	# from flask.views import View
	
	
	class ListView(views.View):
	    def dispatch_request(self):
	        return "类视图"
	
	
	# 类视图通过 add_url_rule 方法和 url 做映射
	# 并且在 as_view 方法中指定该 url 的名称, 方便 url_for 函数调用
	app.add_url_rule('/list/', view_func=ListView.as_view("lv"))



2.2、基于调度方法的视图

        Flask 还为我们提供了另外一种类视图 flask.views.MethodView,对每个 HTTP 方法执行不同的函数(映射到对应方法的小写的同名方法上)。这里介绍一款可以模拟浏览器各种请求的软件 Postman

	class LoginView(views.MethodView):
	    def get(self):
	        return render_template("login.html")
	
	    def post(self):
	        name = request.form.get("name")
	        pwd = request.form.get("pwd")
	
	        if (name == "xxx" and pwd == "123"):
	            return "登录成功!"
	        else:
	            # 当登录失败时, 再次跳转到登录页面 并提示错误
	            return render_template("login.html", error="账号密码错误")
	            
	            
	app.add_url_rule('/lg/', view_func=LoginView.as_view("lg"))

因为 get 与 post 的返回基本相同,所有还可以稍微优化一下代码

	class LoginView(views.MethodView):
	    def get(self, error):
	        return render_template("login.html", error=error)
	
	    def post(self):
	        name = request.form.get("name")
	        pwd = request.form.get("pwd")
	
	        if (name == "xxx" and pwd == "123"):
	            return "登录成功!"
	        else:
	            return self.get("账号密码错误")
	            
	            
	app.add_url_rule('/lg/', view_func=LoginView.as_view("lg"))

当然还可以把 render_template 单独拿出来封装成函数,根据需要传参数。

    def rend_temp(self, *args, **kwargs):
        return render_template("login.html")



2.3、在类视图中使用装饰器

        用类视图的一个缺陷就是比较难用装饰器来装饰,要在类视图中定义一个属性叫做 decorators 的列表变量,然后存储装饰器。如登录之后才能访问

	# 登录之后才能访问的装饰器
	def login_required(func):
	    def wrapper(*args, **kwargs):
	        # 获取 ? 类型 url(get 提交)
	        username = request.args.get("username")
	        if username:
	            return func(*args, **kwargs)
	        else:
	            return "请先登录"
	    return wrapper
	
	
	class ProfileView(views.View):
	    # 在类中用装饰器
	    decorators = [login_required]
	
	    def dispatch_request(self):
	        return "个人页面"
	
	
	app.add_url_rule('/pv/', view_func=ProfileView.as_view("pv"))
发布了145 篇原创文章 · 获赞 1 · 访问量 5849

猜你喜欢

转载自blog.csdn.net/qq_43621629/article/details/105587467