• Flask05 cookie、类视图、方法视图、自己的404页面


    1 什么是cookie

      就是网站存放到你浏览器中的一部分固定内容;当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我
            你要先登录(用户名、密码) ->    我作为后台,会将能够唯一识别你的信息数据存在你的浏览器中    ->    下次你再访问我的时候,你的浏览器就会自动将这些数据返回给我    ->    如果我发现你已经登录过来,我就会让你免去登录步骤
      例子(自动登录):
        你是我的网站用户,你登录完我的网站(如果你选择了记住密码和自动登录);如果我在后台获取到你的相关信息后再到数据库查询对应数据,如果正确就会将这些登录信息存放到你的浏览器中,当你下次访问我的网站是就会自动进行登录

       注意:
              浏览器只能删除cookie,不能进行修改;
              只要你存放着我网站的cookie,那么,下次你访问我的时候就一定会把这个cookie信息传给我

    2 如何查看cookie信息

      谷歌浏览器  ->  设置  ->  高级  ->  内容设置  ->  cookie

    3 如何设置cookie

      cookie是服务器通过响应设置的,所以需要用到Response对象,后台向前端返回的是一个Response对象

      3.1 构造出Response对象

        resp = make_response('设置cookie成功')

          注意:make_response方法返回的是一个Response对象

      3.2 利用Response对象的set_cookie方法来设置cookie信息

        resp.set_cookie('name', 'Warrior')

          注意:通过make_response方法得到的Response对象在pycharm编辑器中不会自动进行代码补全,所以点击后也看不到源代码;但是我们可以通过Response这个类来查看set_cookie方法的源代码

            Response.set_cookie()  点击set_cookie后就可以查看源代码啦(前提:需要导入Response这个类)

      3.3 视图函数返回Response对象即可

        return resp  

    from flask import Flask
    from flask import make_response, Response
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        # Response.set_cookie()  # 用于查看源代码
        # def set_cookie(self, key, value='', max_age=None, expires=None,
        #                path='/', domain=None, secure=False, httponly=False):
        resp = make_response('设置cookie成功') # 创建Response对象
        resp.set_cookie('name', 'Warrior') # 通过Response对象设置cookie
        return resp # 返回Response对象
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

      3.4 设置后的效果

        

      3.5 注意

        每次设置完cookie后,在查询效果前需要刷新一下

        cookie数据必须是字符串类型否则会报错

    4 如何拿到cookie数据

      通过请求对象去获取cookie数据

      4.1 导入request对象

        from flask import request

      4.2 访问reques对象的cookies属性

        request.cookies

      4.3 查看request对象的cookies属性的类型

        print(type(request.cookies))

          打印出的结果为:<class 'werkzeug.datastructures.ImmutableTypeConversionDict'>

            显而易见,这是一个class类,查看这个类的方法如下

              根据打印出的类型信息,导入相关信息

                from werkzeug.datastructures import ImmutableTypeConversionDict

                  点击ImmutableTypeConversionDict后就可以看到源码啦,从源码中可以知道这个ImmutableTypeConversionDict类是继承与Dict类的,所以Dict类拥有的方法和属性ImmutableTypeConversionDict类都可以使用

      4.4 打印request对象的cookie属性信息

        print(request.cookies)

          打印结果为:{'name': 'Warrior', 'age': '24'}    这个结果是一个字典,原因已经在4.3阐明清楚啦

      4.5 如何获取指定的那个cookie信息

        name = request.cookies.get('name')

    from flask import Flask
    from flask import make_response, Response
    from flask import request
    
    from werkzeug.datastructures import ImmutableTypeConversionDict
    
    app = Flask(__name__)
    
    # 利用Response对象设置cookie
    @app.route('/')
    def index():
        # Response.set_cookie()  # 用于查看源代码
        # def set_cookie(self, key, value='', max_age=None, expires=None,
        #                path='/', domain=None, secure=False, httponly=False):
        resp = make_response('设置cookie成功') # 创建Response对象
        resp.set_cookie('name', 'Warrior') # 通过Response对象设置cookie
        resp.set_cookie('age', '24')
        return resp  # 返回Response对象
    
    # 利用Request对象获取cookie数据
    @app.route('/get/')
    def get():
        print(request.cookies) # 打印所有的cookie数据
        print(type(request.cookies)) # 打印resqust对象cookie属性的类型
        name = request.cookies.get('name') # 获取单个的cookie数据
        return '获取到的名字为:'+name
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

    5 设置cookie的保持时间

      cookie默认的保持时间是永久有效(即:关闭浏览器客户端之前都是有效的),时间单位是秒

      

      resp.set_cookie('age', '24')

        

       resp.set_cookie('name', 'Warrior', max_age=60)

        

    from flask import Flask
    from flask import make_response, Response
    from flask import request
    
    from werkzeug.datastructures import ImmutableTypeConversionDict
    
    app = Flask(__name__)
    
    # 利用Response对象设置cookie
    @app.route('/')
    def index():
        # Response.set_cookie()  # 用于查看源代码
        # def set_cookie(self, key, value='', max_age=None, expires=None,
        #                path='/', domain=None, secure=False, httponly=False):
        resp = make_response('设置cookie成功')
        resp.set_cookie('name', 'Warrior', max_age=60)
        resp.set_cookie('age', '24')
        return resp  # 返回Response对象
    
    # 利用Request对象获取cookie数据
    @app.route('/get/')
    def get():
        print(request.cookies) # 打印所有的cookie数据
        print(type(request.cookies))
        name = request.cookies.get('name')
        age = request.cookies.get('age')
        return '获取到的名字为:age = ' + name + "     " + "获取到的年纪为:age = " + age
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)

    6 设置访问路径

      cookie默认的访问路径是所有路径

      

      resp.set_cookie('name', 'Warrior', path='/test/')

        该cookie只有路径开头是 /test/ 的才能够访问到

        

      resp.set_cookie('age', '24')

        该cookie所有的路径都能够访问到

        

    7 设置访问域名

      不进行设置时,那么只有设置cookie那个域名下可以访问到cookie信息;一般情况下是不需要进行设置的,如果需要利用子域名进行访问时就必须进行设置

      resp.set_cookie('name', 'Warrior', domain='.xiangxu.com')

        将该cookie设置成 xiangxu.com 及其子域名下都可以进行访问

      

    from flask import Flask
    from flask import make_response, Response
    from flask import request
    from flask import Blueprint
    
    from werkzeug.datastructures import ImmutableTypeConversionDict
    
    app = Flask(__name__)
    app.config['SERVER_NAME'] = 'xiangxu.com:5000' # 设置域名访问
    
    bp = Blueprint('moive', __name__, subdomain='zeus')
    
    # 利用子域名访问cookie
    @bp.route('/get/')
    def action():
        print(request.cookies)  # 打印所有的cookie数据
        print(type(request.cookies))
        name = request.cookies.get('name')
        age = request.cookies.get('age')
        return '获取到的名字为:age = ' + str(name) + "     " + "获取到的年纪为:age = " + str(age)
    app.register_blueprint(bp)
    
    
    # 利用Response对象设置cookie
    @app.route('/')
    def index():
        # Response.set_cookie()  # 用于查看源代码
        # def set_cookie(self, key, value='', max_age=None, expires=None,
        #                path='/', domain=None, secure=False, httponly=False):
        resp = make_response('设置cookie成功')
        resp.set_cookie('name', 'Warrior', domain='.xiangxu.com')
        resp.set_cookie('age', '24')
        return resp  # 返回Response对象
    
    # 利用Request对象获取cookie数据
    @app.route('/get/')
    def get():
        print(request.cookies) # 打印所有的cookie数据
        print(type(request.cookies))
        name = request.cookies.get('name')
        age = request.cookies.get('age')
        return '获取到的名字为:age = ' + str(name) + "     " + "获取到的年纪为:age = " + str(age)
    
    # 利用不同路径访问cookie
    @app.route('/test/get/', endpoint='testGet')
    def get():
        print(request.cookies) # 打印所有的cookie数据
        print(type(request.cookies))
        name = request.cookies.get('name')
        age = request.cookies.get('age')
        return '获取到的名字为:age = ' + name + "     " + "获取到的年纪为:age = " + age
    
    
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

    8 设置是否JS代码可以访问cookie

      默认情况下可以通过JS代码访问cookie信息

      resp.set_cookie('name', 'Warrior', httponly=True)

      

      

     9 类视图及其使用

      视图函数不能面向对象编程,利用类视图来代替视图函数来解决这个问题

      9.1 导入视图类 View

        from flask.views import View

      9.2 编写一个视图子类

    class MyView(View): # MyView继承于View
    
        def test(self):  #  自定义的方法
            return '测试类视图'
    
        def dispatch_request(self):   # 必须重写这个方法
            resp = self.test()
            return resp

      9.3 利用View子类获取到一个视图方法

        MyView.as_view('test')

          注意:.as_view方法的放回值是一个方法,而且该方法的名字就是传进去的参数

      9.4  将获取到的视图方法和路径对应起来

        app.add_url_rule('/test/', view_func=MyView.as_view('test')) # MyView.as_view('test') 返回的是一个方法

      9.5 类视图的原理

        as_view方法返回的结果赋值给view_func
        as_view方法返回的是一个方法(注意:as_view方法传入的参数就是as_view返回的那个方法的名字),该方法会调用dispatch_request方法
        一旦路由进来,就会调用 dispatch_request 方法
        类视图的目的就是实现逻辑分离、方便管理

    from flask import Flask
    from flask.views import View
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return 'Hello World'
    
    class MyView(View): # MyView继承于View
    
        def test(self):  #  自定义的方法
            return '测试类视图'
    
        def dispatch_request(self):   # 必须重写这个方法
            resp = self.test()
            return resp
    
    
    app.add_url_rule('/test/', view_func=MyView.as_view('test')) # MyView.as_view('test') 返回的是一个方法
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    # 把as_view方法返回的结果赋值给view_func
    # as_view方法返回的是一个方法(注意:as_view方法传入的参数就是as_view返回的那个方法的名字),该方法会调用dispatch_request方法
    # 一旦路由进来,就会调用 dispatch_request 方法
    # 类视图的目的就是实现逻辑分离、方便管理
    View Code

     

    10 方法视图及其使用

      利用视图函数实现不同的请求执行不同的逻辑时比较复杂,需要在视图函数函数中进行判断;如果利用方法视图实现就比较简单

    @app.route('/test/', methods=['GET', 'POST'])
    def test():
        if request.method == 'GET':
            # 做GET的事情
            pass
        elif request.method == 'POST':
            # 做POST的事情
            pass
        return '测试'

      10.1 导入方法视图类  

        from flask.views import MethodView

      10.2 创建方法视图子类

    class TestMethodView(MethodView):
        def get(self):
            # 处理Get请求
            return 'GET请求'
        def post(self):
            # 处理post请求
            return 'POST请求'

        注意:视图类中的方法就是支持的请求类型

          

      10.3 利用方法视图子类创建一个视图函数

        TestMethodView.as_view('testMethodView')

           注意:as_view返回的是一个视图函数,而且该视图函数逇名称就是传进去的参数

       10.4 将获取到的视图方法和路径对应起来

          app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))

    from flask import Flask
    from flask import request
    from flask.views import MethodView
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return '测试主页面'
    
    @app.route('/test/', methods=['GET', 'POST'])
    def test():
        if request.method == 'GET':
            # 做GET的事情
            pass
        elif request.method == 'POST':
            # 做POST的事情
            pass
        return '测试'
    
    class TestMethodView(MethodView):
        def get(self):
            # 处理Get请求
            return 'GET请求'
        def post(self):
            # 处理post请求
            return 'POST请求'
    
    app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))
    # method = TestMethodView.as_view('testMethodView');
    # app.add_url_rule('/test02/<name>/', view_func=method, methods=['GET'])
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

      10.5 虽然在方法视图中定义的函数就是支持的请求类型,但是我们可以在配置路径时指定哪个路径对应哪中类型的请求

        10.5.1 利用方法视图子类获取一个名字为testMethodView02的视图函数,该视图函数只能支持GET请求,而且支持转换器

    method02 = TestMethodView.as_view('testMethodView02');
    app.add_url_rule('/test02/<name>/', view_func=method02, methods=['GET'])

        10.5.2 利用利用方法视图子类获取一个名字为testMethodView03的视图函数,该视图函数只能支持POST请求

    method03 = TestMethodView.as_view('testMethodView03')
    app.add_url_rule('/test03/', view_func=method03, methods=['POST'])

          模拟POST请求

            

    from flask import Flask
    from flask import request
    from flask.views import MethodView
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return '测试主页面'
    
    @app.route('/test/', methods=['GET', 'POST'])
    def test():
        if request.method == 'GET':
            # 做GET的事情
            pass
        elif request.method == 'POST':
            # 做POST的事情
            pass
        return '测试'
    
    class TestMethodView(MethodView):
        def get(self, name):
            # 处理Get请求, 也可以在这些方法中调用其他的方法
            return 'GET请求' + name
        def post(self):
            # 处理post请求, 也可以在这些方法中调用其他的方法
            return 'POST请求'
    
    # app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))
    method02 = TestMethodView.as_view('testMethodView02');
    app.add_url_rule('/test02/<name>/', view_func=method02, methods=['GET'])
    method03 = TestMethodView.as_view('testMethodView03')
    app.add_url_rule('/test03/', view_func=method03, methods=['POST'])
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

    11 编写统一的404页面

      11.1 导入abort方法

        from flask import abort

      11.2 设置一个站位符,当404错误出现时,自己编写的404页面就会在占位符的位置进行显示

        abort(404)  

       11.3 利用钩子编写自己的404页面

    @app.errorhandler(404)  # 404页面钩子
    def page_404(er):  # 参数是原始的404页面提示信息
        print(er)
        return '这是统一的错误页面', 404, {}  # 返回自己编写的404页面信息

      

    from flask import Flask
    from flask import abort
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return '测试主页面'
    
    movies = [1,2,3,4,5]
    
    @app.route('/movie/<int:num>/')
    def movie(num):
        if num in movies:
            return '电影 {} 的详细信息为:...... '.format(num)
        abort(404)  # 自己编写的404页面会显示在这里
    
    @app.errorhandler(404)  # 404页面钩子
    def page_404(er):  # 参数是原始的404页面提示信息
        print(er)
        return '这是统一的错误页面', 404, {}  # 返回自己编写的404页面信息
    
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code
  • 相关阅读:
    线程的异常捕获与线程池的异常捕获
    设计模式-状态模式
    老王讲自制RPC框架.(四.序列化与反序列化)
    老王讲自制RPC框架.(三.ZOOKEEPER)
    老王讲自制RPC框架.(二.动态代理)
    4
    3
    2
    1
    前言
  • 原文地址:https://www.cnblogs.com/NeverCtrl-C/p/7535751.html
Copyright © 2020-2023  润新知