• 9、Flask实战第9天:类视图


    之前我们接触的视图都是函数,所以一般简称为视图函数。其实视图函数也可以基于类来实现,类视图的好处是支持继承,写完类视图需要通过app.add_url_rule(url_rule, view_func)来进行注册

    标准类视图

    1、标准类视图必须继承flask.views.View

    2、必须实现dispatch_request方法,以后请求过来后,都会执行这个方法,这个方法的返回值相当于之前的视图函数一样,也必须返回Response或者子类的对象,或者是字符串、元祖

    3、必须通过app.add_url_rule(rule, endpoint, view_func)来做url与视图的映射,view_func这个参数,需要使用as_view类方法转换

    4、如果指定了endpoint,那么在使用url_for反转的时候就必须使用endpoint指定的那个值。如果没有指定endpoint,那么就可以使用as_view(视图名字)中指定的视图名字来作为反转

    ...
    from flask import views
    
    class ListView(views.View):
        def dispatch_request(self):
            return 'my list'
    
    app.add_url_rule(rule='/list/', endpoint='list', view_func=ListView.as_view('list'))

    view_func=ListView.as_view('list')为什么要这样用呢,这是因为view_func是接收函数的,而ListView是一个类,通过as_view方法转换出来的就是一个函数,而这个函数实际上就是dispatch_request, 里面的‘list’是给这个视图函数取的一个名字。 我们可以按住ctrl点击as_view查看源码,就知道返回的是dispatch_request

    对比类视图和函数视图,似乎类视图用起来的比麻烦。其实在很多场景是有用处的,因为类可以继承,这里我们来举个例子:
    比如在登录页面和注册页面,我们都放一个同样的广告,如果我们是视图函数,就需要这样写:

    @app.route('/login/')
    def login():
        context = {
            'ads': 'python入门到精通'
        }
        return render_template('login.html', **context)
    
    @app.route('/register/')
    def register():
        context = {
            'ads': 'Python入门到精通'
        }
        return render_template('register.html', **context)

    使用这种方法明显存在一个缺点:就是当广告需要更换的时候,两个视图函数都需要更改,如果我们使用类视图,就可以使用继承来解决

    class AdsView(views.View):
        def __init__(self):
            super().__init__()
            self.context = {
                'ads': 'Python高级进阶'
            }
    
    
    class LoginView(AdsView):
        def dispatch_request(self):
            return render_template('login.html', **self.context)
    
    
    class RegisterView(AdsView):
        def dispatch_request(self):
            return render_template('login.html', **self.context)
    
    
    app.add_url_rule(rule='/login/', endpoint='login', view_func=LoginView.as_view('login'))
    app.add_url_rule(rule='/register/', endpoint='register', view_func=RegisterView.as_view('register'))

    基于调度方法的类视图

    Flask还为我们提供了另外一种类视图flask.views.MethodView,对每个HTTP方法执行不同的函数

    我们来模拟做一个登录页面,  一般登录我们会用到两种方法,当进入登录页面的时候我们会用get方法,当我们填好表单点击登录的时候会用到post方法

    class LoginView(views.MethodView):
        def get(self):
            return render_template('login.html')
    
        def post(self):
            username = request.form.get('username')
            password = request.form.get('password')
            if username == 'heboan' and password == '123456':
                return '登录成功'
            else:
                return render_template('login.html', error='登录失败')
    
    app.add_url_rule(rule='/login/', endpoint='login', view_func=LoginView.as_view('login'))

    login.html

    <form action="" method="post">
        <table>
            <tr>
                <td>用户名:</td>
                <td><input name="username" type="text" /></td>
            </tr>
    
            <tr>
                <td>密码:</td>
                <td><input name="password" type="password" /></td>
            </tr>
            <tr>
                <td><input type="submit" value="登录"></td>
            </tr>
        </table>
    
        {% if error %}
            <p style="color: red">登录失败</p>
        {% endif %}
    
    </form>

    其实还可以对这段代码进行优化。我们发现我们一开是进入登录页面,和登录失败都是返回login.html

    class LoginView(views.MethodView):
        def __render(self, error=None):
            return render_template('login.html', error=error)
    
        def get(self):
            return self.__render()
    
        def post(self):
            username = request.form.get('username')
            password = request.form.get('password')
            if username == 'heboan' and password == '123456':
                return '登录成功'
            else:
                return self.__render(error='登录失败')
    
    app.add_url_rule(rule='/login/', view_func=LoginView.as_view('login'))
  • 相关阅读:
    如何添加看板娘(转载的)
    golang gin LoadHTMLGlob 加载模板文件
    wpf Popup 不跟随窗口移动的问题
    golang 在vscode 安装插件失败的解决方法
    javaweb + tomcat + 部署 + 域名绑定 + 默认首页
    【RabbitMQ】三种Exchange模式——订阅、路由、通配符模式
    一切的浮点型进行计算操作都要用BigDecimal
    如何让mysql按照两个或多个字段排序
    JAVA枚举操作(获取值,转map集合)
    gitlab 配置 ssh key
  • 原文地址:https://www.cnblogs.com/sellsa/p/9248178.html
Copyright © 2020-2023  润新知