flask CBV写法/中间件/异常捕获/请求与响应/session/请求扩展

flask cbv写法

基于类的视图写法

from flask import Flask, request
from flask.views import MethodView, View

app = Flask(__name__)
app.debug = True

# 必须要继承MethodView这个类来编写
class LoginView(MethodView):
    def get(self):
        print(request.method)
        return 'get'

    def post(self):
        print(request.method)
        return 'post'


app.add_url_rule('/login', view_func=LoginView.as_view('login'), endpoint='login')
# 对视图函数添加路由,

# Login.as_view('必须传参数') 传入的参数会被当作别名,endpoint是别名的意思 当然也可以不传
# 别名是项目中不可以重复的



	  -1 as_view 执行流程跟djagno一样
    -2 路径如果不传别名(endpoint属性),别名默认是as_view('login')的传参数
    -3 视图函数加多个装饰器(上下顺序和必须传endpoint)
       例如:你加入了一个验证是否登录的装饰器 
        
        @app.route('/home', methods=['GET', 'POST'],endpoint='home')
        @login
        def home():
          return 'home'
  使用装饰器,如果再加认证装饰器,那么应该放在路由装饰器上还是下?
	-放在路由下面
  -路由必须传endpoint,如果不传,又报错
        
        
    -4 视图类必须继承MethodView,否则需要重写dispatch_request
    -5 视图类加装饰器:类属性decorators = [auth,]
    
    
    

if __name__ == '__main__':
    app.run()
    # app.run('127.0.0.1',5000)
    # 可以设置访问地址和端口号,不写默认本地5000端口


视图类加装饰器

from flask import Flask, request
from flask.views import MethodView, View

app = Flask(__name__)
app.debug = True

# 必须要继承MethodView这个类来编写

# 8 视图类加装饰器,直接配置在类属性上【decorators】配置即可
class LoginView(MethodView):
  	decorators = [auth,]
	# 就会把下面的函数当作是参数 传入 auth中
	
    def get(self):
        print(request.method)
        return 'get'

    def post(self):
        print(request.method)
        return 'post'
      
      
app.add_url_rule('/login', view_func=LoginView.as_view('login'), endpoint='login')

模版

前后端一体的flask项目  前端的模版要统一放在 templates文件夹中

from flask import Flask, render_template,Markup

a='<a href="http://www.baidu.com">点我看美女</a>
如果是一个标签需要渲染的话 可以使用 Markup方法
a=Markup(a)
这样包裹传递到前端就可以直接当作链接使用了


也可以传递一个函数到前端
def add(a,b):
    return a+b
{{add(4,5)}}
# 前端可以直接使用这个函数 传递参数即可 会得到函数的返回值

return render_template('index.html',name='lqz',a=a,add=add)
# 通过render_template方法可以 渲染出页面 并直接可以给页面传递数据,

请求与响应

请求:全局的request对象
from flask import Flask, request

@app.route('/', methods=['GET', 'POST'])
def index():
    #### 请求
    # request.method  提交的方法 get/post 
    # request.args  get请求提及的数据  请求头传递的数据
    # request.form   post请求提交的数据   请求体里面的数据
    # request.values  post和get提交的数据总和
    # request.cookies  客户端所带的cookie  
    # request.headers  请求头 kv形式 可以通过 User-Agent拿到访问设备
	# Host是访问网址和端口,
    # request.path     不带域名,请求路径
    # request.full_path  不带域名,带参数的请求路径
    # request.script_root
    # request.url           带域名带参数的请求路径
    # request.base_url    带域名请求路径
    # request.url_root      域名
    # request.host_url    域名
    # request.host       127.0.0.1:500

    obj = request.files['file']
    # 这样可以直接把文件拿出来 ['上传的文件名']
    obj.save(obj.filename)
    # 然后把这个文件直接保存到当前路径下
	
	
    
from flask import Flask, request,make_response

响应中写数据
把需要返回的响应内容包装成一个对象 用make_response方法
然后在这个对象中添加 cookie 或 其他数据

response = 'hello'
res = make_response(response)
res.set_cookie('xx':'xx')
res.headers['yy']='yy'
# 响应头中加入数据
return res



session的使用

cookie:存放在客户端的键值对
session:存放在客户端的键值对
token:存放在客户端,通过算法来校验


from flask import session

当用户登录成功以后可以直接将一些数据 保存到session中
session都是以kv键值对的形式存储在前端的

'''
虽然是全局导入的session 但是每一个请求的session都是不一样的
'''

app.secret_key = 'asdfas33asdfasf'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        name = request.form.get('name')
        password = request.form.get('password')
        session['name'] = name
        # 设置session的方法 k为name valus为name的
        return redirect('/index')
      
      
@app.route('/index', methods=['GET', 'POST'])
def index():
    return 'hello %s' % session.get('name', '匿名用户')
  	# 取出前端session中 的name ,如果没有默认值为 匿名用户
    # 取出session的方法 
    
    
设置:session['username']'xxx'
删除:session.pop('username', None)
取值:session.get('name', '匿名用户')

session的源码

有两个非常重要的方法,请求来了,会执行open_session,请求走了会执行save_session
      def open_session(self, app, request) :
		#1 根据名字,取出前端传入的cookie的value值
        val = request.cookies.get(self.get_cookie_name(app))
        #2 如果没有val,构造了一个空session对象
        if not val:
            return self.session_class()
        max_age = int(app.permanent_session_lifetime.total_seconds())
        try:
            # 如果没有过期,解码,做成session对象,后续直接用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) :
        name = self.get_cookie_name(app)
		# 取出过期事件,和把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,)
        
        
        
        
  # 扩展,想把session放到redis中,mysql中,已经有人帮咱们写了,第三方的
	只需要写个类,重写open_session,save_session自己写

闪现

跨请求存储数据,例如第一次请求获得了一个数据,第二次请求可以再取出来

实现了跨请求存储数据。

from flask import flash,get_flashed_messages

当次请求,访问出错,被重定向到其他地址,重定向到这个地址后,拿到当时的错误

存数据 多次存储默认是尾部追加 
flash('%s,我存了'%name)

获取数据 取的话一次性就会获取所有之前存的数据 并且会把数据删除 只能拿一次
get_flashed_messages() 

-假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息


flash('超时错误',category="x1")
设置一个键为x1 值为 超时错误的键值对
data = get_flashed_messages(category_filter=['x1'])
取出键值为x1的值

请求扩展(中间件)

请求来执行,请求走执行

你对那个函数装上当请求来了或者走的时候就会执行哪个函数

如果在请求来的时候 直接返回return那就不会再往下走 就走不到视图函数了

1.before_request
请求来的时候

#基于它做用户登录认证
@app.before_request
# 装上了这个装饰器,那么请求来的时候就会执行这个代码
def process_request(*args,**kwargs):
    if request.path == '/login':
        return None
    user = session.get('user_info')
    if user:
        return None
    return redirect('/login')
  
  
2.after_request
请求走的时候

@app.after_request
def index1(response):
    # 必须要传参数response
    print('请求走了')
    return response
  
  
@app.before_request
def index():
    print('请求来了')


@app.before_request
def index2():
    print('请求来了2')

    
@app.after_request
def index1(response):
    # 必须要传参数response
    print('请求走了')
    return response

  
@app.after_request
def index1(response):
    # 必须要传参数response
    print('请求走了2')
    return response
  
请求来时时从上倒下。 请求走时 从下到上
执行顺序:请求来了,请求来了2,请求走了2,请求走了



3.teardown_request
@app.teardown_request
def teardown(error):
    print(error)
# 当函数被执行时就会触发这个代码  可以用来记录日志

全局异常捕获

捕捉错误响应码的 

@app.errorhandler(403)
def error_404(arg):
    return "禁止访问"


@app.errorhandler(404)
def error_404(arg):
    return "404请求资源不存在"
  
@app.errorhandler(500)
def error_404(arg):
    return "500错误了"
  
  
@app.errorhandler(503)
def error_404(arg):
    return "503服务器维护中"
  
@app.errorhandler(504)
def error_404(arg):
    return "504网络延迟"
posted @   Python-moon  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示