首页 > 其他分享 >Flask 学习-22.可插拨视图MethodView类

Flask 学习-22.可插拨视图MethodView类

时间:2022-08-27 22:55:09浏览次数:54  
标签:users Flask MethodView url 视图 user func view

前言

可插拨视图基于使用类来代替函数,其灵感来自于 Django 的通用视图。可插拨视图的主要用途是用可定制的、可插拨的视图来替代部分 实现。

基本原理

假设有一个函数用于从数据库中载入一个对象列表并在模板中渲染:

@app.route('/users/')
def show_users(page):
    users = User.query.all()
    return render_template('users.html', users=users)

上例简单而灵活。但是如果要把这个视图变成一个可以用于其他模型和模板的通用视图, 那么这个视图还是不够灵活。因此,我们就需要引入可插拨的、基于类的视图。第一步, 可以把它转换为一个基础视图:

from flask.views import View

class ShowUsers(View):

    def dispatch_request(self):
        users = User.query.all()
        return render_template('users.html', objects=users)

app.add_url_rule('/users/', view_func=ShowUsers.as_view('show_users'))

就如你所看到的,必须做的是创建一个 flask.views.View 的子类,并且执行 dispatch_request() 。然后必须通过使用 as_view() 方法把类转换为实际视图函数。

插拨视图可以像普通函数一样加入应用。加入的方式有两种,一种是使用 route() ,另一种是使用更好的 add_url_rule() 。在加入的视图中应该提供所使用的 HTTP 方法的 名称。提供名称的方法是使用 methods 属性:

from flask.views import View
from flask import request


class MyView(View):
    # 定义请求方法
    methods = ["GET", "POST"]

    # get请求
    def get(self):
        return "get"

    # post请求
    def post(self):
        return "post"

    # 调度函数,必须重写。不重写,View类会直接抛异常
    def dispatch_request(self):
        # 请求方法映射关系
        request_method = {"get": self.get, "post": self.post}
        # 通过requset方法获取前端访问的请求方法
        print(request.method)
        # 通过请求方法,映射到对应的函数对象
        view = request_method.get(request.method.lower())
        # 返回映射到的函数返回值
        return view()

# 注册,用as_view方法
app.add_url_rule("/my", view_func=MyView.as_view("myview"))

看到这可能已经蒙圈,前面是讲基本实现原理,dispatch_request()方法必须要自己重写,并且不好理解怎么去写它,接下来讲简单的实现方式,让大家轻轻松松学会。

MethodView 基于方法调度

MethodView是 前面View 的升级版本,不需要我们写dispatch_request()方法了,接下来看下面更优雅的实现方式

from flask.views import View, MethodView


class MyView(MethodView):

    def get(self):
        return {"code": 0, "msg": "get 请求"}

    def post(self):
        return {"code": 0, "msg": "post 请求"}


# 注册,用as_view方法
app.add_url_rule("/my", view_func=MyView.as_view("myview"))

使用这种方式,不必提供 methods 属性,它会自动使用相应 的类方法。
于是发get请求,得到结果

GET http://127.0.0.1:5000/my 

{
  "code": 0,
  "msg": "get 请求"
}

发post请求,得到结果

POST http://127.0.0.1:5000/my

{
  "code": 0,
  "msg": "post 请求"
}

实现restful API风格接口

网络 API 经常直接对应 HTTP 变量,因此很有必要实现基于 MethodView 的 API 。即多数时候, API 需要把不同的 URL 规则应用到同一个方法视图。例如,假设你需要这样使用一个 user 对象:

URL 方法 说明
/users/ GET 给出一个包含所有用户的列表
/users/ POST 创建一个新用户
/users/ GET 显示一个用户
/users/ PUT 更新一个用户
/users/ DELETE 删除一个用户

那么如何使用 MethodView 来实现呢?方法是使用多个规则对应 到同一个视图。

假设视图是这样的:

class UserAPI(MethodView):

    def get(self, user_id):
        if user_id is None:
            # 返回一个包含所有用户的列表
            pass
        else:
            # 显示一个用户
            pass

    def post(self):
        # 创建一个新用户
        pass

    def delete(self, user_id):
        # 删除一个用户
        pass

    def put(self, user_id):
        # update a single user
        pass

那么如何把这个视图挂接到路由系统呢?方法是增加两个规则并为每个规则显式声明 方法:

user_view = UserAPI.as_view('user_api')
app.add_url_rule('/users/', defaults={'user_id': None},
                 view_func=user_view, methods=['GET',])
app.add_url_rule('/users/', view_func=user_view, methods=['POST',])
app.add_url_rule('/users/<int:user_id>', view_func=user_view,
                 methods=['GET', 'PUT', 'DELETE'])

如果你有许多类似的 API ,那么可以代码如下:

def register_api(view, endpoint, url, pk='id', pk_type='int'):
    view_func = view.as_view(endpoint)
    app.add_url_rule(url, defaults={pk: None},
                     view_func=view_func, methods=['GET',])
    app.add_url_rule(url, view_func=view_func, methods=['POST',])
    app.add_url_rule('%s<%s:%s>' % (url, pk_type, pk), view_func=view_func,
                     methods=['GET', 'PUT', 'DELETE'])

register_api(UserAPI, 'user_api', '/users/', pk='user_id')

装饰视图

视图函数会被添加到路由系统中,而视图类则不会。因此视图类不需要装饰,只能以手工 使用 as_view() 来装饰返回值:

def user_required(f):
    """Checks whether user is logged in or raises error 401."""
    def decorator(*args, **kwargs):
        if not g.user:
            abort(401)
        return f(*args, **kwargs)
    return decorator

view = user_required(UserAPI.as_view('users'))
app.add_url_rule('/users/', view_func=view)

自 Flask 0.8 版本开始,新加了一种选择:在视图类中定义装饰的列表:

class UserAPI(MethodView):
    decorators = [user_required]

请牢记:因为从调用者的角度来看,类的 self 被隐藏了,所以不能在类的方法上单独 使用装饰器。

标签:users,Flask,MethodView,url,视图,user,func,view
From: https://www.cnblogs.com/yoyoketang/p/16631728.html

相关文章

  • Flask 学习-21. 项目配置通过.env环境变量启动开发/生产环境
    前言一般一个项目会配置多套环境:开发/测试/生产环境,每套环境的配置不一样,比如不同的运行环境配置的数据库不一样。config配置在前面的配置管理中https://www.cnblogs.co......
  • Flask 学习-20. route 路由中的 endpoint 参数
    前言@app.route中的endpoint参数,就相当于django中的name参数,用来反向生成URL。url_for()函数url_for()函数用于构建指定函数的URL。它把函数名称作为第一个参数。......
  • flask 解决日志重复打印问题 or Python日志重复打印
    背景:业务代码上线后,莫名会重复输出很多相同的日志,已知以为是多线程问题,后仔细了解期logging原理后发现并非如此。以下为解决方案fromflaskimportFlaskas_Flaskfro......
  • Flask 学习-19.配置管理flask_sqlalchemy 和 flask_migrate
    前言前面讲了项目中使用config.py可以管理开发、生产、测试等环境的配置,这篇继续学习在项目中添加flask_sqlalchemy和flask_migrate的配置环境准备先pip安装flask_s......
  • 17 - Docker来部署flaskDemo项目
    README.md文件内容:#flaskDemo本接口项目的技术选型:Python+Flask+MySQL+Redis,通过Python+Flask来开发接口使用MySQL来存储用户信息使用Redis用于存储token目......
  • Flask 学习-17.项目配置管理config
    前言项目总是需要一定的配置的。根据应用环境不同,会需要不同的配置。比如开关调试模式、设置密钥以及其他依赖于环境的东西。配置入门我们写的第一个helloworld应用......
  • # flask_socket_io中报错RuntimeError: You need to use the eventlet server. See th
    flask_socket_io中报错RuntimeError:Youneedtousetheeventletserver.SeetheDeploymentsectionofthedocumentationformoreinformation.的解决办法https:/......
  • flask socket cros
    flasksocketcroshttps://flask-socketio.readthedocs.io/en/latest/api.html......
  • flask-restful使用指南
    flask-restful是flask模块的一个扩展,能够快速构建restful风格的api。对于其他的扩展也有很高的兼容性。安装flask_restfulpipinstallflask_restful简单使用fromfl......
  • 框架-视图层(WXSS)
    WXSSWXSSWXSS(WeiXinStyleSheets)是一套样式语言,用于描述WXML的组件样式。WXSS用来决定WXML的组件应该怎么显示。为了适应广大的前端开发者,WXSS具有CSS大部......