赞
踩
原文档:
flask 源码解析:上下文
文章中 承上启下,
程序中: 根据已经写完,完成的代码,以及即将要完成的代码,去决定当前时刻要完成的或者要是使用的变量和方法
当请求进入时,flask会自动激活请求上下文,这时可以使用request和session变量。当请求上下文被激活时,程序上下文也被自动激活。
除了上面四个上下文变量,依赖上下文的还有url_for()和jsonify()函数,所以只能在视图函数中使用它们。其中jsonify()函数内部调用中使用了current_app变量,url_for()则需要依赖请求上下文才可以正常运行。
g存储在程序上下文中,而程序上下文会随着每一个请求的进入而激活,随着每一个请求的处理完毕而销毁,所以每次请求都会重设这个g值。
我们通常会使用它结合钩子来保存每个请求处理前所需要的全局变量。
类似于全局变量
from flask import Flask,Blueprint,request from flask import current_app,g g_views = Blueprint("goods_views",__name__) @g_views.before_request def demo01(): user_name = request.args.get("username") g.user_name = user_name def outer(func): def inner(): ## 通过request 获取了用户的username ## 查询到了用户的 user_id user_id = 1 g.user_id = user_id return func() return inner @g_views.route("/index/") @outer def index(): ### 也需要获取用户id ### request 获取到用户的username ## 查询用户 user_id user_id = g.user_id user_name = g.user_name print (user_id) print (user_name) mymd5() return "goods views index" def mymd5(): ## md5 需要密钥 ##从app的配置文件中 取到 密钥 ## 第一种 导入app 从app中取配置信息 app.config["SECRET_KEY"] # config = current_app.config value = config.get("SECRET_KEY") print(value) return "我是加密后的结果"
from flask import Flask,Blueprint from flask import current_app g_views = Blueprint("goods_views",__name__) @g_views.route("/index/") def index(): mymd5() return "goods views index" def mymd5(): ## md5 需要密钥 ##从app的配置文件中 取到 密钥 ## 第一种 导入app 从app中取配置信息 app.config["SECRET_KEY"] # current_app使用方法 config = current_app.config value = config.get("SECRET_KEY") print(value) return "我是加密后的结果"
flask为上下文提供了一个teardown_appcontext钩子,使用它注册的毁掉函数会在程序上下文被销毁时调用,通常也在请求上下文被销毁时调用,比如你需要在每个请求处理结束后销毁数据库连接:
@app.teardown_appcontext
def teardown_db(exception):
db.close()
app.reardown_appcontext装饰器注册的回调函数需要接收异常对象作为参数,当请求被正常处理时这个参数将是None,这个函数的返回值将被忽略
上下文钩子类似于django的中间件
django中间件中有以下几个方法:
在干预请求和响应之间,flask中提供了四个这样的钩子:
flask中使用钩子,需要使用装饰器去使用
具体如下:
from flask import Flask app = Flask(__name__) #### @app.before_first_request #### 当第一个请求到达的时候执行 def demo01(): """ demo01 这个函数: 做一些项目的初始化配制 :return: """ print ("before_first_request") @app.before_request def demo02(): ### 获取用户的信息 ### 获取用户的session cookie ### 校验用户的身份 print("before_request") print("before_request") userid = request.args.get("id") if not userid: return "缺少请求信息" @app.after_request def demo03(response): print ("after_request") ## 构建返回的结构 return response @app.teardown_request def demo04(response): print (response) print("teardown_request") @app.route("/index/") def index(): #### 1/0 return "index" if __name__ == '__main__': app.run()
将一个功能的最小模块进行测试,测试的目的:是否满足预期
登录功能:
单元测试需要程序员自己编写
断言:assert
如果assert后面的表达式是一个 True ,表示断言成功,如果为一个false,断言失败,抛出异常
assert 1>2,"真理是2大于1"
test.py
编写单元测试代码
执行:
python manage.py test appname
单元测试在python中,用到 unittest模块 (单例模式)
import unittest class MyTest(unittest.TestCase): def setUp(self): """ 在测试执行之前执行,用来加载 准备测试参数 :return: """ self.a = 10 self.b = 11 ## 需要写测试代码 ## 测试方法必须的要求 test_ 开头 def test_demo(self): self.assertEquals(self.a,self.b,msg="a 和 b 不相等") def test_demo_has_id(self): pass def tearDown(self): """ 在测试之后执行,用于回收测试环境 :return: """ pass if __name__ == '__main__': unittest.main() ## 启动测试
import unittest ## 导入 create这个工厂方法 from app import Create from settings import TestConfig import json class TestMyTest(unittest.TestCase): def setUp(self): self.app = Create(TestConfig) self.client = self.app.test_client() ## 属于flask 提供的测试方法 def test_has_id(self): # 给 mytest 这个路由 发出get请求 传递id参数 # 拿到返回值 # 判断返回值是否满足我们的预期 #发送get请求 使用urllib和requests发送请求,必须需要flask服务开启的 ## 第二种 使用flask提供的方法进行get,post,put,delete请求,不需要开启flask服务 resp = self.client.get("/mytest/?id=1") ## 首先应该看一下 返回的状态码 200 self.assertEquals(resp.status_code,200) ## 判断返回值 是否符合预期 result_data =resp.data ### 返回的 结果 result_data = result_data.decode() data = json.loads(result_data) ## 反序列化 ## 判断返回值中时候有data self.assertIn("data",data) ## 判断 data 是否在返回值中包含 ## 判断返回值中 code 是否为 10000 self.assertEquals(data["code"],10001) def test_no_id(self): pass def tearDown(self): pass if __name__ == '__main__': unittest.main()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。