• 4-flask-cbv源码、Jinja2模板、请求响应、flask中的session、flask项目参考


    1 flask中cbv源码
    2 Jinja2模板
    3 请求响应
    4 flask中的session
    5 flask项目参考

    1 flask中cbv源码

    ***flask的官网文档:***
    	https://flask.palletsprojects.com/en/3.0.x/views/
    
        
    1 cbv源码执行流程
    	'''
    	1 请求来了,路由匹配成功---》执行ItemAPI.as_view('item')()--->view加括号执行
    	2 ItemAPI.as_view('item')执行结果:就是View中as_view方法中的闭包函数 view
    	3 view()--->执行self.dispatch_request()---》执行MethodView的dispatch_request
    	def dispatch_request(self, **kwargs):
    	    meth = getattr(self, request.method.lower(), None)
    	    return meth(**kwargs)
    	4 如果是get请求,就会执行视图类中的get方法
    	
    	class View:
    	    @classmethod
    	    def as_view()
    	        def view():
    	            self.dispatch_request()
    	        return view
    	'''
    
    
    2  endpoint 的使用
    	app.add_url_rule('/item', endpoint='xxx',view_func=ItemAPI.as_view('item'))
    	如果写了endpoint---》别名以它为准,如果不写以as_view的参数为准
    
    3 逻辑:
    	1 app.add_url_rule('/item',endpoint='xxx', view_func=ItemAPI.as_view('item'))
    	2 endpoint = _endpoint_from_view_func(view_func)
    	    如果endpoint没传,就会走这句
    	    view_func 是  ItemAPI.as_view('item')  它就是 view
    	    
    	3 _endpoint_from_view_func(view_func)---》返回了传入的函数的名字
    		return view_func.__name__
    	
    	4 如果上面传入了ItemAPI.as_view('item'),它的函数名就是view---》endpoint就是view
    
    
    ## 总结:
    	endpoint如果不传,会以视图函数的函数名作为endpoint
        	-fbv:如果不写endpoint,会以函数名作为endpoint,但是如果多个视图函数加了同一个装饰器,又没有指定endpoint,就会出错了
            -cbv:调用as_view一定要传入一个字符串---》如果endpoint没写,endpoint就是传入的这个字符串,如果写了,这个字符串没用
            
        如果传了,直接以endpoint传入的作为endpoint
        
        
        
    ### cbv中加装饰器
    	1 使用步骤:在类中加入类属性:
            class ItemAPI(MethodView):
                decorators = [装饰器,装饰器2]
                def get(self):
                    # print(url_for('xxx'))
                    print(url_for('item'))
                    return 'get'
    	2 
           if cls.decorators:
              for decorator in cls.decorators:
                    view = decorator(view)   
                    '''
                    @装饰器
                    def view()
                    '''
    
    
    • 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
    ### 整个cbv执行流程
    # View的as_view
    @classmethod
    def as_view(cls, name, *class_args, **class_kwargs) :
           def view(**kwargs):
                return self.dispatch_request(**kwargs)
    
            if cls.decorators:   # 咱们的装饰器
                for decorator in cls.decorators: #每次拿出一个装饰器,
                    view = decorator(view) # 装饰器语法糖干的事: 把被装饰的函数当参数传入到装饰器,返回结果赋值给被装饰的函数,一个个用装饰器包装view
            view.__name__ = name
            return view
        
    
    # self.dispatch_request---》MethodView
    def dispatch_request(self, **kwargs) :
        # 取到request.method.lower()请求方式小写 ---》假设是get请求get
        # meth是 cbv中 以get命名的方法,反射出来了
        meth = getattr(self, request.method.lower(), None)
        return meth(**kwargs) # 执行cbv中跟请求方式同名的方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    def register_api(app, model, name):
        item = ItemAPI.as_view(f"{name}-item", model)
        group = GroupAPI.as_view(f"{name}-group", model)
        app.add_url_rule(f"/{name}/", view_func=item)  # get put  delete
        app.add_url_rule(f"/{name}/", view_func=group)   #post get 
    
    register_api(app, User, "users")
    register_api(app, Story, "stories")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2 Jinja2模板

    # flask使用了Jinja,flask提供了文档,也可以去Jinja官网看
    https://flask.palletsprojects.com/en/3.0.x/
    https://jinja.palletsprojects.com/en/3.1.x/
        
        
    # 总结:之前学过dtl
    	-{{变量/简单表达式/函数}}
        -{%if/for %} {%endif%}  {%endfor%}
        -比dtl强大 ,Jinja中可以加括号
        -字典取值,列表取值跟python语言一样,之前dtl 通过 .取值
        -过滤器,标签
        -extends,include 跟之前一样
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3 请求响应

    # 所有web:请求对象,响应对象(go,java,ptyhon)
    	django:request(每个请求一个request),新手四件套
        flask: requset:全局的,但是也是每个请求一个request,新手三件套
    
    # request  全局对象,用起来,跟之前django的一样
            # request.method  请求的方法
            # request.args  get请求提交的数据
            # request.form   post请求提交的数据
            # request.values  post和get提交的数据总和
            # request.cookies  客户端所带的cookie
            # request.headers  请求头
            # request.path     不带域名,请求路径
            # request.full_path  不带域名,带参数的请求路径
            # request.url           带域名带参数的请求路径
            # request.base_url		带域名请求路径
            # request.url_root      域名
            # request.host_url		域名
            # request.host			服务端地址
            # request.files
            # obj = request.files['the_file_name']
            # obj.save('/var/www/uploads/' + secure_filename(f.filename))
            
            
            
            
    # 响应 response---》四件套
    	-return '字符串'
    	-return render_template('index.html',name=lqz,age=19)
    	-return redirect(url_for(别名))
    	-return jsonify(字典,列表) 
    
    	# 往cookie中写数据--->四件套需要使用
    	obj=make_response('index')
        obj.set_cookies()  # 跟之前一样
        
        # obj.headers[]
    
    • 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

    4 session

    # cookie 机制
    # 设置
    obj=make_response('index')
    obj.set_cookies('name','lqz')
    # 取
    request.cookie.get('name')
    
    
    # session机制
    	1 设置秘钥
        2 写入session
        session['username']='xxx'
        3 取出session
        username = session.get('username')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    5 flask项目参考

    # 开源项目阅读
    https://toscode.mulanos.cn/pear-admin/pear-admin-flask
        
    # 1 git clone https://toscode.mulanos.cn/pear-admin/pear-admin-flask
    # 2 使用pycharm打开
    # 3 创建虚拟环境,装依赖
    # 4 改配置文件
       MYSQL_USERNAME = "root"
        MYSQL_PASSWORD = "lqz123?"
        MYSQL_HOST = "127.0.0.1"
        MYSQL_PORT = 3306
        MYSQL_DATABASE = "PearAdminFlask"
    
        # 数据库的配置信息
        # SQLALCHEMY_DATABASE_URI = 'sqlite:///../pear.db'
        SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{urlquote(MYSQL_PASSWORD)}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}?charset=utf8mb4"
        
        
    # 5 创建数据库  PearAdminFlask
    
    
    # 6 执行初始化
    	flask db init
        
    #7 migrate.bat
    # 8 flask admin init
    # 9 启动
    run.bat
    
    # 10 改代码---》密码不判断
    
    
    
    • 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
  • 相关阅读:
    急!新版PMP考试考试通过率高吗?怎样才能提高我考试通过的几率?
    业务前端界面报错504排查思路和解决办法
    Typescript 学习笔记(二)高级类型一
    [干货]LangChain入门-LangChain框架的构成与特点
    第一季:3类和实例初始化【Java面试题】
    React封装自定义表单校验方法
    openRPA开源项目源码编译
    数据大屏指南 | 一屏看世界,一点选专业
    猴子也能学会的jQuery第一期——什么是jQuery
    so easy,用 Python 实现图片转字符画
  • 原文地址:https://blog.csdn.net/weixin_44145338/article/details/134441641