• 3-falsk-登录认证装饰器、类装饰器、flask的配置使用方式、flask的内置配置、flask的路由系统、 CBV(基于类的视图)


    1 flask中登录认证装饰器
    1.1 补充:类装饰器
    1.1 加在类上的装饰器
    1.2 类作为装饰器
    1.3 类装饰器装饰类
    1.4 有参装饰器

    2 配置文件
    2.1 flask配置使用方式
    2.2 flask的内置配置

    3 flask的路由系统
    4 CBV基于类的视图

    1 flask中登录认证装饰器

    from flask import Flask, request, render_template, redirect, session, jsonify, url_for
    
    app = Flask(__name__)
    # 如果要用session,必须加这一句
    app.secret_key = 'asdfasdfasdf-lqz-justin'
    USERS = {
        1: {'name': '李清照', 'age': 18, 'gender': '男',
            'text': "刘亦菲,1987年8月25日出生于湖北省武汉市,华语影视女演员、歌手,毕业于北京电影学院2002级表演系本科",
            'img': 'https://img2.woyaogexing.com/2021/10/16/e3ccba623848430ba83209c0621a2256!400x400.jpeg'},
        2: {'name': '彭于晏', 'age': 28, 'gender': '男',
            'text': "彭于晏,1982年3月24日出生于中国台湾省澎湖县,毕业于不列颠哥伦比亚大学,华语影视男演员。。。。。。。。",
            'img': 'https://img2.woyaogexing.com/2021/10/16/e71aa35728c34313bccb4c371192990f!400x400.jpeg'},
        3: {'name': '迪丽热巴', 'age': 38, 'gender': '女',
            'text': "迪丽热巴(Dilraba),1992年6月3日出生于中国新疆乌鲁木齐市,毕业于上海戏剧学院,中国内地影视女演员",
            'img': 'https://img2.woyaogexing.com/2021/10/30/6a34146dde2d4f1c832463a5be1ed027!400x400.jpeg'},
        4: {'name': '亚瑟', 'age': 38, 'gender': '男',
            'text': "亚瑟,是腾讯手游《王者荣耀》中一名战士型英雄角色,也是《王者荣耀》的新手英雄之一,既可攻又可守",
            'img': 'https://img2.woyaogexing.com/2021/10/30/371b2aa7a03c4f53b7b1bc86f877d7d1!400x400.jpeg'},
    }
    
    
    def auth(func):
        def inner(*args, **kwargs):
            # 判断是否登录---session是全局的直接用即可
            username = session.get('username')
            if username:
                res = func(*args, **kwargs)
                return res
            else:
                return redirect(url_for('login'))
    
        return inner
    
    
    
    @app.route('/login11', methods=['GET', 'POST'], endpoint='login')
    def login():
        if request.method == 'GET':
            return render_template('login.html')
        else:
            username = request.form.get('username')
            password = request.form.get('password')
            if username == 'lqz' and password == '123':
                # 登录成功,把登录信息,写入到session中
                session['username'] = username
                # 登录成功,重定向到首页
                # return redirect('http://www.baidu.com')
                return redirect('/')
            else:
                return render_template('login.html', error='用户名或密码错误')
    
    
    @app.route('/', methods=['GET'], endpoint='index')
    @auth
    def index():
        return render_template('index.html', user_dict=USERS)
    
    
    @app.route('/detail/', endpoint='detail')
    @auth
    def detail(pk):
        user = USERS.get(pk)
        return render_template('detail.html', user=user)
    
    
    
    '''
    1 只要函数被装饰器装饰器了,以后被装饰的函数,就都叫 inner了
    2 只要在路由装饰器上加endpoint属性,就可以解决这个问题
    3 endpoint等同于djagno路由中的name --》给路由命别名---》可以通过反向解析,通过名字找到路径
    4 url_for 做路由反向解析---》需要使用endpoint指定的名字
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    1.1 补充:类装饰器

    类装饰器
    	- 加在类上的装饰器
        - 类作为装饰器
    
    # 1 给类加装饰器----》在装饰器中,可以控制对象的产生过程,以及修改对象(给对象加属性或方法)--》增强了对象
    
    
    # 2 类作为装饰器---》必须要写 __init__ 和 __call__--->原来装饰器在执行被装饰函数之前或之后的代码,都写在__call__中
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.1 加在类上的装饰器

    1 加在类上的装饰器---》如果装饰器什么都不写,类用起来跟之前一样
    2 如果装饰器中对 对象  进行一些操作,只要加了这个装饰器,所有类产生的对象,
      都会走装饰器inner内的操作
    
    def auth(func):
        def inner(*args, **kwargs):
            res = func(*args, **kwargs)
            # res 是 Person类的对象
            res.name = '彭于晏'
            res.age=99
            return res
    
        return inner
    
    
    @auth  # Person=auth(Person)--->以后Person就变成了 inner
    class Person():
        def __init__(self, name):
            self.name = name
    
    
    print('------', type(Person))  # Person就变成了 inner,不影响后续使用
    
    p = Person('lqz')
    p1=Person('sdasfsd')
    print(p.name)
    print(p.age)
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    1.2 类作为装饰器

    
    class Auth():
        def __init__(self, func):
            print('傻逼')
            self.func = func
    
        def __call__(self, *args, **kwargs):
            print('执行了')
            res = self.func(*args, **kwargs)
            return res
    
    
    @Auth  # add=Auth(add) ---> 后续add就是Auth的对象了----》add(1,2)--->Auth类对象()
    def add(a, b):
        return a + b
    
    
    res = add(1, 2)  # Auth的对象家括号---->会触发类的__call__
    print(res)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.3 类装饰器装饰类

    
    class Auth():
        def __init__(self, func):
            self.func = func
    
        def __call__(self, *args, **kwargs):
            print('我执行了')
            res = self.func(*args, **kwargs)
            print('执行完了')
            return res
    
    
    @Auth  # Person=Auth(Person)
    class Person:
        pass
    
    
    p = Person()  # Person()---->本质是谁? Auth(Person)()---》触发Auth的__call__
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.4 有参装饰器

    1 有参装饰器--->额外为被装饰的函数传参数
    2 什么是有参装饰器---》之前咱们的装饰器,都不加括号---》如果有参装饰器,装饰器加括号
    
    3 在装饰器内部,有些动态参数,是通过传参传过来的,就可以使用有参装饰器
    
    • 1
    • 2
    • 3
    • 4
    def auth(name):
        def outter(func):
            def inner(*args, **kwargs):
                res = func(*args, **kwargs)
                return res
            return inner
        return outter
    
    name='彭于晏'
    
    @auth(name)  # add=auth('lqz')(add)
    def add(a,b):
        return a+b
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2 配置文件

    2.1 flask配置使用方式

    from flask import Flask
    
    app = Flask(__name__)
    
    ## 1 方式一:直接在app中修改,只能改以下两个
    app.debug=True
    app.secret_key='asdfasdf'
    
    ## 2 使用py文件方式---》跟django一样
    app.config.from_pyfile('./settings.py')
    print(app.config)  # 就是所有配置信息---》就是django 的 from django.conf import settings
    print(app.config.get("DEBUG"))
    print(app.config.get("MYSQL_HOST"))
    
    
    ## 3 类的方式--》以后写出多个类,上线和测试完全分开
    app.config.from_object('settings.ProductionConfig')
    app.config.from_object('settings.DevelopmentConfig')
    print(app.config.get('DEBUG'))
    print(app.debug)
    print(app.debug is app.config.get('DEBUG'))
    
    
    # 4 其他--》了解
    app.config.from_envvar("环境变量名称")
    # 环境变量的值为python文件名称名称,内部调用from_pyfile方法
    
    app.config.from_json("json文件名称")
    # JSON文件名称,必须是json格式,因为内部会执行json.loads
    
    app.config.from_mapping({'DEBUG': True})
    
    # 5 配置中心---》apollo和nacos区别
    app.config.from_mapping(config_data)
    
    @app.route('/')
    def index():
        return 'hello sd'
    
    if __name__ == '__main__':
        app.run()
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    2.2 flask的内置配置

    {
      'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式
      'TESTING':                              False,                          是否开启测试模式
      'PROPAGATE_EXCEPTIONS':                 None,                          
      'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
      'SECRET_KEY':                           None,
      'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
      'USE_X_SENDFILE':                       False,
      'LOGGER_NAME':                          None,
      'LOGGER_HANDLER_POLICY':               'always',
      'SERVER_NAME':                          None,
      'APPLICATION_ROOT':                     None,
      'SESSION_COOKIE_NAME':                  'session',
      'SESSION_COOKIE_DOMAIN':                None,
      'SESSION_COOKIE_PATH':                  None,
      'SESSION_COOKIE_HTTPONLY':              True,
      'SESSION_COOKIE_SECURE':                False,
      'SESSION_REFRESH_EACH_REQUEST':         True,
      'MAX_CONTENT_LENGTH':                   None,
      'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
      'TRAP_BAD_REQUEST_ERRORS':              False,
      'TRAP_HTTP_EXCEPTIONS':                 False,
      'EXPLAIN_TEMPLATE_LOADING':             False,
      'PREFERRED_URL_SCHEME':                 'http',
      'JSON_AS_ASCII':                        True,
      'JSON_SORT_KEYS':                       True,
      'JSONIFY_PRETTYPRINT_REGULAR':          True,
      'JSONIFY_MIMETYPE':                     'application/json',
      'TEMPLATES_AUTO_RELOAD':                None,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    3 flask的路由系统

    '''
    1 flask 路由是基于装饰器的
        -rule:路径,不能写正则
        -methods=['GET','POST] :允许的请求方式
        -endpoint: 当前路由的别名---》反向解析用
    2 转换器: 
    
    | `string` | (default) 任意字符串类型,不能带 /     |
    | `int`    | 接收正整数                             |
    | `float`  | accepts positive floating point values |
    | `path`   | 带 / 的string                          |
    | `uuid`   | accepts UUID strings                   |
    
    3 其他写法
    @app.route  + methods  不写methods 默认只有get
        -@app.get
        -@app.post
    
    4 路由系统本质
        -装饰器---》本质是  self.add_url_rule(rule, endpoint, f, **options)
        -self是 Flask(__name__) app对象
        -自己注册路由,不使用装饰器
        app.add_url_rule('/', view_func=index)
        app.add_url_rule('/home', view_func=home)
    4 其他参数:add_url_rule  本质就是在研究app.route 除了view_func之外的所有参数
        1 rule, URL规则
        2 view_func, 视图函数名称
        3 defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'} 为函数提供参数
        4 endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
        5 methods = None, 允许的请求方式,如:["GET", "POST"]
        6 strict_slashes = None  #对URL最后的 / 符号是否严格要求
        7 redirect_to = None,#重定向到指定地址
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    string(default) 任意字符串类型,不能带 /
    int接收正整数
    floataccepts positive floating point values
    path带 / 的string
    uuidaccepts UUID strings
    from flask import Flask
    
    app = Flask(__name__)
    app.debug = True
    '''
    1 flask 路由是基于装饰器的
        -rule:路径,不能写正则
        -methods=['GET','POST] :允许的请求方式
        -endpoint: 当前路由的别名---》反向解析用
    2 转换器: 
    
    | `string` | (default) 任意字符串类型,不能带 /     	 |
    | `int`    | 接收正整数                             	 |
    | `float`  | accepts positive floating point values  |
    | `path`   | 带 / 的string                           |
    | `uuid`   | accepts UUID strings                    |
    
    3 其他写法
    @app.route  + methods  不写methods 默认只有get
        -@app.get
        -@app.post
    
    4 路由系统本质
        -装饰器---》本质是  self.add_url_rule(rule, endpoint, f, **options)
        -self是 Flask(__name__) app对象
        -自己注册路由,不使用装饰器
        app.add_url_rule('/', view_func=index)
        app.add_url_rule('/home', view_func=home)
    4 其他参数:add_url_rule  本质就是在研究app.route 除了view_func之外的所有参数
        1 rule, URL规则
        2 view_func, 视图函数名称
        3 defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'} 为函数提供参数
        4 endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
        5 methods = None, 允许的请求方式,如:["GET", "POST"]
        6 strict_slashes = None  #对URL最后的 / 符号是否严格要求
        7 redirect_to = None,#重定向到指定地址
    '''
    
    
    def index():
        return 'he'
    
    
    def home():
        return 'html'
    
    
    @app.route('/login', redirect_to='/home')
    def login():
        return 'login'
    
    
    app.add_url_rule('/', view_func=index)
    app.add_url_rule('/home', view_func=home)
    
    if __name__ == '__main__':
        app.run()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    4 CBV基于类的视图

    from flask import Flask, url_for
    from flask.views import MethodView
    
    app = Flask(__name__)
    app.debug = True
    
    
    ### 1 cbv写法
    class LoginView(MethodView):
        # decorators = [auth]
        methods = ['get','post']  # 允许的请求方式
    
        def get(self):
            return 'get'
    
        def post(self):
            print(url_for('login'))
            return "post"
    
    
    # 注册路由
    # LoginView.as_view('login') 参数是别名
    app.add_url_rule('/login', view_func=LoginView.as_view('login'))
    
    ### 2 cbv加装饰器,直接加在视图类的方法上---》第一个参数必须是self,需要额外处理
    # 在类中直接写 decorators = [auth]  按之前装饰器的样子用即可
    
    
    ### 3 methods的用法
    # methods = ['get', 'post']  # 允许的请求方式
    
    
    ## 4 MethodView继承了View,View中有as_view方法---》本质是执行了dispatch_request-->View没有写dispatch--》MethodView写了所以,视图类必须要继承MethodView
    ## 如果非要继承View,匹配方式,需要自己写
    
    if __name__ == '__main__':
        app.run(port=8080)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
  • 相关阅读:
    B端产品设计流程--产品定位
    雷达编程实战之静态杂波滤除与到达角估计
    Spring 源码(17)Spring Bean的创建过程(8)Bean的初始化
    一个简单的vim例子
    [Pytorch] 保存模型与加载模型
    Java简系 - Java基础概念「二」
    转载)word输出高分辨PDF并且有链接跳转功能
    制作一个简单HTML旅游网站(HTML+CSS+JS)无锡旅游网页设计与实现8个页面
    MySQL:存储引擎
    代码随想录算法训练营第23期day38|动态规划理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
  • 原文地址:https://blog.csdn.net/weixin_44145338/article/details/134420449