Falsk三

CBV源码

官网:https://flask.palletsprojects.com/en/3.0.x/views/

cbv源码执行流程

请求来了,路由匹配成功,执行ItemAPI.as_view('item')()--->view加括号执行

ItemAPI.as_view('item')执行结果:就是View中as_view方法中的闭包函数 view(源码中as_view返回值是view)

 view()--->执行self.dispatch_request()---》执行MethodView的dispatch_request

def dispatch_request(self, **kwargs):
meth = getattr(self, request.method.lower(), None)
return meth(**kwargs)
如果是get请求,就会执行视图类中的get方法

endpoint使用

app.add_url_rule('/item', endpoint='xxx',view_func=ItemAPI.as_view('item'))
如果写了endpoint---》别名以它为准,如果不写以as_view的参数为准

逻辑:

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、

 装饰器放入一个列表,靠前的装饰器放在最里面,靠后的放在外面

fbv装饰器时如果多个函数使用同一个装饰器,必须加上endpoint,不然会将函数名字改成装饰器内部名字,导致报错。

 

整个cbv的执行流程

### 整个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中跟请求方式同名的方法

模板

flask使用了Jinja,flask提供了文档,也可以去Jinja官网看
https://flask.palletsprojects.com/en/3.0.x/
https://jinja.palletsprojects.com/en/3.1.x/

总结:

之前学过dtl,

dtl只需要记两种特殊符号:

{{  }} 和 {% %}

变量相关的用{{}}:{{变量/简单表达式/函数}}

逻辑相关的用{%%}:{%if/for %} {%endif%}  {%endfor%}

比dtl强大 ,Jinja中可以加括号

字典取值,列表取值跟python语言一样,之前dtl 通过 .取值

过滤器,标签

extends,include 跟之前一样

 

请求响应

 所有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() # 跟之前一样

 

session

cookie机制

设置:

obj=make_response('index')
obj.set_cookies('name','l')

取:

request.cookie.get('name')

session机制:

1、 设置秘钥

 2 、写入session  session['username']='xxx'

3 、取出session

 username = session.get('username')

 

posted @ 2023-11-16 18:53  别管鱼油我了  阅读(6)  评论(0编辑  收藏  举报