首页 > 编程语言 >flask 请求与响应,session使用与源码分析,闪现与请求扩展

flask 请求与响应,session使用与源码分析,闪现与请求扩展

时间:2023-04-03 18:00:12浏览次数:43  
标签:__ return 请求 session flask app request 源码 name

目录

cbv分析

基于类的视图

cbv写法

from flask import Flask,request
# 视图基类
from flask.views import MethodView

app = Flask(__name__)

app.DEBUG = True


# 视图类,继承MethodView
class IndexView(MethodView):
    def get(self):
        print(request.method)
        return 'get'

    def post(self):
        return 'post'


app.add_url_rule('/', endpoint='index', view_func=IndexView.as_view('index'))

if __name__ == '__main__':
    app.run()

源码分析

Indexview.as_view('index') 执行完的结果,return反回了view方法
as_view(c1s,name,*class_args,**class_kwargs):
	def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
       # 本质是在执行self.dispatch_request 用异步
		return current_app.ensure_sync(self.dispatch_request)(**kwargs)
   return view

# 请求来了就是在执行 MethodView里的 dispatch_request
    def dispatch_request(self, **kwargs):
        # 去self(视图类的对象) 拿到请求方法
        meth = getattr(self, request.method.lower(), None)
        if meth is None and request.method == "HEAD":
            meth = getattr(self, "get", None)
        assert meth is not None, f"Unimplemented method {request.method!r}"
        # 用异步执行meth()
        return current_app.ensure_sync(meth)(**kwargs)

总结

1 as_view 执行流程跟djagno一样
2 路径如果不传别名,别名就是函数名(endpoint)
3 视图函数加多个装饰器
# 上下顺序(放在下面)和必须传endpoint(不传其实用的都是装饰器内部的函数,所以需要传)
4 视图类必须继承MethodView,否则需要重写dispatch_request
5 视图类加装饰器:类属性decorators = [auth,]

模板

py文件

from flask import Flask, render_template,Markup

app = Flask(__name__, template_folder='templates', static_folder='static')  # 模板的路径必须是templates,因为实例化app对象时,传入的
app.debug=True


def add(a,b):
    return a+b
@app.route('/')
def index():
    a='<a href="http://www.baidu.com">点我看美女</a>'  # 不存在xss攻击,处理了xss
    a=Markup(a)  # 可以在这包,模板里就可以不用safa了
    return render_template('index.html',name='lqz',a=a,add=add) 


if __name__ == '__main__':
    app.run()

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>模板语法,static</h1>
<img src="/static/1.jpg" alt="">

<h1>模板语法,if</h1>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}

<h1>模板语法,标签渲染</h1>
{{a|safe}}
{{a}}

<h1>模板语法,执行函数</h1>
{{add(4,5)}}

</body>
</html>

请求与响应

请求: 全局的request

from flask import Flask, request,make_response

app = Flask(__name__)
app.debug = True


@app.route('/',methods=['GET','POST'])
def index():
    print(request.method)    # 请求方式
    print(request.args)      # 获取get请求参数   是个字典
    print(request.form)      # 获取post请求参数
    print(request.values)    # 获取get和post请求参数
    print(request.cookies)   # 获取cookie
    print(request.headers)   # 获取请求头
    print(request.path)      # 获取根路径
    print(request.full_path) # 获取完整的请求路径 带过滤参数
    print(request.url)       # 获取请求url
    print(request.base_url)   # 获取请求的基础url
    print(request.url_root)   # 获取请求的根路径
    print(request.host_url)   # 获取请求的主机路径
    print(request.host)      # 获取请求的主机
    print(request.files)     # 获取上传的文件
    # 保存文件
    obj=request.files.get('file')
    obj.save(obj.filename)  #  obj.filename获取文件名,以文件名保存

if __name__ == '__main__':
    app.run()

响应: 新手四件套

from flask import Flask, request,make_response

app = Flask(__name__)
app.debug = True


@app.route('/',methods=['GET','POST'])
def index():
    # 响应就是四件套, render_template,redirect,return,jsonify
    # 1 . 往响应里面添加cookie,先产生一个response对象
    res = make_response('hello world')  # make_response,需要导入,返回的是一个response对象
    # 修改
    res.set_cookie('name','tank')
    # 2. 响应头中写数据
    res.headers['name']='tank'
    return res


if __name__ == '__main__':
    app.run()

session使用及源码分析

from flask import Flask, request, session,render_template,redirect

app = Flask(__name__)
app.debug = True

# 用session,必须设置secret_key
app.secret_key = '21312sadasd35'


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        name = request.form.get('name')
        pwd = request.form.get('pwd')
        # 添加session
        session['name'] = name
        return redirect('/index')


@app.route('/index', methods=['GET', 'POST'])
def index():
    return 'hello %s' % session.get('name','游客')

if __name__ == '__main__':
    app.run()

cookie与session

cookie 存在与客户端浏览器的键值对

session 存在于服务端的键值对 ,在django中放在了django_session表中

flask 把session加密后放到了cookie中,存入的是一个字符串,session发生了变化cookie里存入的字符串也会跟着变化。

session执行原理

image

session源码分析

app.session_interface 进入 ,发现配置了一个类的对象,它就是session的执行流程

 session_interface: SessionInterface = SecureCookieSessionInterface()

SecureCookieSessionInterface 类中有两个重要的方法

open_sessionsave_session

    def open_session(self, app, request):
        s = self.get_signing_serializer(app)
        if s is None:
            return None
        # 根据config里配置的session名字取出前端传入的cookie的value值
        val = request.cookies.get(self.get_cookie_name(app))
        # 如果没有值, 狗仔一个空的session对象
        if not val:
            return self.session_class()
        max_age = int(app.permanent_session_lifetime.total_seconds())
        try:
            # 如果没过期,解密做成session对象
            data = s.loads(val, max_age=max_age)
            return self.session_class(data)
        except BadSignature:
         # 若果过期了也是空的session
            return self.session_class()
 def save_session(self, app, session, response):
	`	 # session没有直接删除cookie
        if not session:
            if session.modified:
                response.delete_cookie(
                    name,
                    domain=domain,
                    path=path,
                    secure=secure,
                    samesite=samesite,
                    httponly=httponly,
                )

            return
        if session.accessed:
            response.vary.add("Cookie")

        if not self.should_set_cookie(app, session):
            return
		 # 取出过期时间,把session加密转成字符串,放到cookie中
        expires = self.get_expiration_time(app, session)
        val = self.get_signing_serializer(app).dumps(dict(session))
        response.set_cookie(
            name,
            val,  
            expires=expires,
            httponly=httponly,
            domain=domain,
            path=path,
            secure=secure,
            samesite=samesite,
        )

扩展

把session放到redis/mysql 中,需要重写个类,重写open_session与save_session 方法,已经有一个模板帮助我们写好了。 后面说

闪现

什么是闪现

flash 翻译过来的
 当次请求把 数据放入到某个位置,下一次请求,去那个位置把数据取出来,后那个位置数据就没了。

作用

跨请求保存数据

当次请求访问出现错误,被重定向到别的网页,重定向到这个网页里,向拿到元网页出现错误的信息。

django中的message框架也可以做到 不叫闪现 叫消息框架

用法

学习设置闪现与使用闪现

from flask import Flask, flash, get_flashed_messages,request

app = Flask(__name__)
app.secret_key = '21312sasdsa'

# 设置闪现
@app.route('/set_flash')
def set_flash():
    name = request.args.get('name')
    flash('%s我跳出来啦,你打我呀' % name)  # 也要加上secret_key,本质写在session里,可以设置多次会放在一个列表中
    flash('超时',category='debug')  # 分类存
    return '写入了闪现消息'

# 获取闪现
@app.route('/get_flash')
def get_flash():
    res = get_flashed_messages()  # 只会获取一次,获取完就没了
    get_flashed_messages(category_filter=['debug']) # 分类取
    print(res)
    return '获取了闪现消息'


if __name__ == '__main__':
    app.run()
    
"本质就是放在session中"

请求扩展

请求扩展中 : 在请求来或走,可以设置一些函数,到这里就会执行函数。类似与django中间件

在flask 中用请求扩展 代替django的中间件。

from flask import Flask

app = Flask(__name__)


# 请求来执行函数,可以写多个,从上到下执行,多个中间件有一个反回了,就不会执行下面的了,直接走响应回去
@app.before_request
def before_request():
    print('我先摸了她一下')


# 请求走了执行函数,可以写多个,从下到上执行
@app.after_request
def after_request(response):
    print('走了我又摸了她一下')
    return response


# 请求报错了执行函数,可以做错误日志记录
@app.teardown_request
def teardown(e):
    print(e)
    print('报错就会执行我')


# errorhandler 监听响应状态码,404报错就会执行
@app.errorhandler(404)
def error(arg):
    return '404'


@app.route('/')
def index():
    a = [1, 2]
    # print(a[4])
    return 'hello world'


if __name__ == '__main__':
    app.run()

标签:__,return,请求,session,flask,app,request,源码,name
From: https://www.cnblogs.com/LiaJi/p/17283810.html

相关文章

  • flask-
    1.flask写cbv1.1cbv模板之前我们都是写fbv,现在我们写cbv,这样可以把get请求写在一个视图类中:fromflaskimportFlask,requestfromflask.viewsimportView,MethodViewapp=Flask(__name__)'''每次修改之后项目会自己启动'''app.debug=TrueclassIndexView(Meth......
  • Rust如何引入源码作为依赖
    问题描述通常我们在rust项目中引入第三方依赖包时,会直接指定包的版本,这种方式指定后,Cargo在编译时会从crates.io这个源中下载这些依赖包。[package]name="foo"version="0.1.0"edition="2021"[dependencies]j4rs=0.15.3比如这里我们就在项目中引用了j4rs这个包,这......
  • Flask 和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、
    Flask和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、路由系统Flask和pythonweb框架介绍Flask和pythonweb框架的区别:Django框架: 大而全,内置的app很多,第三方的app很多Flask框架: 小而精,没有过多的内置app,只能完成web框架的基本功能,很多功能......
  • spring源码各个版本中的两个字符串比较的变更,值得学习
    判断一个字符串是否空串:1、Spring旧版本使用equals,新版本使用isEmpty()方法;查找String的源码发现isEmpty的底层使用this.value.length==0进行判断。粗略分析:equals在进行比较时耗时约0.1秒,==无耗时。 ......
  • Flask框架cbv的写法、请求与响应、请求扩展、session源码分析、闪现
    本篇文章将会详细讲在flask框架如何写cbv、请求与响应、请求扩展、session源码分析、闪现等知识点。目录一、flask写CBV二、请求与响应三、session四、闪现flash五、请求扩展一、flask写CBVCBV源码分析的结论如下1as_view执行流程跟djagno一样2路径如果不传别名,别名就是......
  • 《渗透测试》信息打点-小程序应用&解包反编译&动态调试&抓包&静态分析&源码架构 2023
     #小程序获取-各大平台&关键字搜索-微信-百度-支付宝-抖音头条 #小程序体验-凡科建站&模版测试上线测试:https://qz.fkw.com/参考:https://blog.csdn.net/qq_52445443/article/details/1223518651.主体结构小程序包含一个描述整体程序的app和多个描述各自页面的pa......
  • js 头像上传(图片截取) 插件 全屏高清版 源码
    先上图片 index.html<!DOCTYPEhtml><html><head><metaname="viewport"content="width=device-width"/><title>ccp</title><linkhref="Content/ccp.css"rel="stylesheet"......
  • FastThreadLocal源码解析
    Netty为什么要用自己的FastThreadLocal?threadLocalHash冲突,检索时间长。Netty自己定义的fastThreadLocal用的是数组,直接数组下标检索快。下面以ftl作为FastThreadLocal的简称例子ftl只有在FastThreadLocalThread线程中运行才生效,不然会走SlowGet模式(jdkthreadLocal方式)publiccl......
  • 1 Flask 和pythonweb框架介绍、2 flask快速使用 、3 登录,显示用户信息小案例、4 配置
    目录1Flask和pythonweb框架介绍1.1flask介绍2flask快速使用3登录,显示用户信息小案例3.1login.html3.2home.html3.3detail.html3.4py文件4配置文件方式5路由系统5.1路由本质5.2路由参数add_url_rule5.3转换器1Flask和pythonweb框架介绍#pythonweb框架,本质都一......
  • 1 cbv分析、2 模板、3 请求与响应 、4 session及源码分析、5 闪现、 6 请求扩展
    目录1cbv分析1.1源码分析2模板2.1py2.2html3请求与响应4session及源码分析4.1session的使用4.2源码分析4.3session执行原理5闪现6请求扩展1cbv分析#基于类的视图,写法fromflaskimportFlask,requestfromflask.viewsimportView,MethodViewapp=Flask(__......