当前位置:   article > 正文

Flask框架(六)--蓝图,请求钩子,上下文,单元测试(Flask,Django)_flask 蓝图钩子

flask 蓝图钩子

一、蓝图–blueprint

类似于django中的app子应用。

flask中,要将项目模块化,就应该使用blueprint,它是flask自带的一种开发模式,目的是方便开发大型的项目。

使用

from flask import Flask,Blueprint

# 实例化一个蓝图对象
# 参数:第一个
bp = Blueprint('goods',__name__)

@bp.route('/index/')
def index():
    return 'index'

if __name__ == '__main__':
    app = Flask(__name__)
    app.config['DEBUG'] = True
    app.register_blueprint(bp,url_prefix='/goods')
    app.run()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

一个项目中多个蓝图

在这里插入图片描述
在这里插入图片描述

使用蓝图整合项目

在这里插入图片描述

二、请求钩子

类似于Django中的中间件。

用来干预请求与相应,flask中提供了四个方法

  • before_first_request
    • 请求到达视图之前,项目被启动之后,第一个请求达到时执行
  • before_request
    • 请求到达视图之前,每次请求到达时执行
  • after_request
    • 在每次请求之后被执行
    • 接收参数:视图处理之后返回的响应
  • teardown_request
    • 在每次请求之后执行
    • 接收参数:错误信息

flask中使用钩子,需要使用装饰器

from flask import Flask,request
app = Flask(__name__)

# 当第一个请求到达的时候执行
@app.before_first_request
def demo01():
    # 可以做一些项目的初始化配置
    print('before_first_request')

@app.before_request
def demo02():
    # 可以获取用户信息
    print('before_request')
    user_id = request.args.get('id')
    if not user_id:
        return '缺少请求信息'

@app.after_request
def demo03(response):
    # 构建返回数据的结构
    print('after_request')
    return response

@app.teardown_request
def demo4(response):
    print(response)
    print('teardown_request')

@app.route('/index/')
def index():
    1/0
    return 'index'

if __name__ == '__main__':
    app.run()
  • 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

在这里插入图片描述
在这里插入图片描述

三、上下文

程序中,根据已经写完的代码,以及即将要完成的代码,决定当前时刻要完成的或者是要使用的变量和方法。

flask当中:

请求上下文

  • request 包含了请求中所有的请求信息
  • session 请求中的session

应用上下文

指的是当前的app

  • g对象

    • 类似于全局变量

      from flask import Blueprint,request,g
      
      g_views = Blueprint('goods_views',__name__)
      
      @g_views.before_request
      def demo01():
          username = request.args.get('username')
          g.username = username
      
      def outer(func):
          def inner():
              user_id = 1
              g.user_id = user_id
              return func()
          return inner
      
      @g_views.route('/index/')
      @outer
      def index():
          user_id = g.user_id
          username = g.username
          print(user_id)
          print(username)
          # mymd5()
          return 'goods views index'
      
      • 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

      在这里插入图片描述
      在这里插入图片描述

  • current_app

    • 代理人

    • 经常用在多蓝图,多视图,多模块的编程中

    • 当某一些模块需要使用app的功能,但不方便直接拿到app时,就需要代理人

      from flask import Blueprint,request,current_app
      
      g_views = Blueprint('goods_views',__name__)
      
      @g_views.route('/index/')
      def index():
          mymd5()
          return 'goods views index'
      
      def mymd5():
          # 从app的配置文件中取密钥
          # 第一种 导入app 从app中获取配置信息
          # app.config['SECRET_KEY']
          # 第二种 利用应用上下文
          config = current_app.config
          value = config.get("SECRET_KEY")
          print(value)
      
          return '加密后结果'
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

      在这里插入图片描述
      在这里插入图片描述

四、单元测试

将一个功能的最小模块进行测试

测试目的:是否满足预期

登录功能:

  • 用户输入的用户民,类型,长度,是否为空
  • 测试根据用户查询到的结果是否满足预期

单元测试,需要程序员自己编写

断言:assert

如果assert后面的表达式是一个True,表示断言成功,如果为一个False,断言失败,抛出异常
在这里插入图片描述

单元测试在python中,用到unittest模块(单例模式)

import unittest

class MyTest(unittest.TestCase):
    def setUp(self):
        '''
        在测试前执行,用来加载和准备测试参数
        '''
        self.a = 10
        self.b = 11
    # 需要写测试代码
    # 测试方法必须的要求  名以text_开头
    def test_demo(self):
        self.assertEquals(self.a,self.b,msg='a 和 b不相等')
    def test_demo_has_id(self):
        pass
    def tearDown(self):
        '''
        在测试执行之后,用于回收测试环境
        '''
        pass
if __name__ == '__main__':
    unittest.main()    # 启动测试
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述

flask

视图
@main.route('/mytest/')def mytest():    id = request.args.get('id')    result = {'code':10000,'msg':'success'}    if id:        result['data'] = 'asdklasjdkl'            return jsonify(result)
  • 1
测试类
import unittest
# 导入create这个工厂方法
from app import create
from settings import Config
import json

class TestMytest(unittest.TestCase):
    def setUp(self):
        self.app = create(Config)
        self.client = self.app.test_client()    # 属于flask提供的测试方法
    def test_has_id(self):
        # 给mytest这个路由,发出get请求,传递id参数
        # 拿到返回值
        # 判断返回值是否满足我们的预期
        # 发送get请求,使用urllib和request发送请求,必须保证flask服务是开启的

        # 还可以使用flask提供的方法进行get,post,put,delete请求,不需要开启flask服务
        response = self.client.get('/mytest/?id=1')
        # 首先应该看一下,响应码是否为200,即是否请求成功
        self.assertEquals(response.status_code,200)
        # 判断返回值,是否符合预期
        result_data = response.data    # 返回的结果
        result_data = result_data.decode()
        data = json.loads(result_data)
        # 判断返回值中是否有data
        self.assertIn('data',data)
        # 判断返回值中code是否为10000
        self.assertEquals(data['code'],10000)
    def test_no_id(self):
        pass
    def tearDown(self):
        pass

if __name__ == '__main__':
    unittest.main()
  • 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

在这里插入图片描述

django

视图
def mytest(request):
    id = request.GET.get('id')
    result = {'code': 10000, 'msg': 'success'}
    if id:
        result['data'] = 'asdklasjdkl'

    return JsonResponse(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
路由

在这里插入图片描述

测试类

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/501447
推荐阅读
相关标签
  

闽ICP备14008679号