Flask的Composite(二):缓存、钩子、四大内置对象、模板和static的路径问题

一.缓存

1.缓存介绍

(1)缓存目的

缓存优化加载,减少数据库的IO操作

(2)实现方案

a.缓存到数据库 b.缓存到文件 c.缓存到内存 d.缓存到内存中的数据库Redis

(3)实现流程

a.从路由函数进入程序
b.路由函数到视图函数
c.视图函数去缓存中查找
d.缓存中找到,直接进行数据返回
e.如果没找到,去数据库中查找
f.查找到之后,添加到缓存中
g.返回到页面上

2.缓存使用

(1)安装 flask-cache

pip install flask-cache

(2)初始化

在ext文件中,指定使用的缓存方案
   cache = Cache(config={‘CACHE_TYPE’:‘redis’})
   cache.init_app(app=app)

(3)flask-cache版本问题

初始化后,在云服务器中启动会报错
在这里插入图片描述
1.这是由于flask更新了,werkzeug也跟着更新,但是flask-cache版本没有更新,所以版本兼容性就出现了问题。此时的flask-cache兼容0.16.1版本的werkzeug。
解决方案:(1)先将werkzeug卸载:pip uninstall werkzeug
     (2)然后安装0.16.1版本:pip install werkzeug==0.16.1
2.解决上面的问题后,又出现No module named 'flask.ext’的问题
在这里插入图片描述
解决方案 :(1)进入到flask-cache的库,然后点击jinja2ext.py
      (2)将from flask.ext.cache import make_template_fragment_key,修改为from flask_cache import make_template_fragment_key
在这里插入图片描述
设置完成后,则能正常运行。

(4)装饰器缓存

在views文件中添加:

@blue.route('/testCache/')
@cache.cached(timeout=20)
def testCache():
    time.sleep(5)#睡眠5秒
    return '测试缓存'

1.这里要引用cache变量,所以是让ext文件中的cache = Cache(config={‘CACHE_TYPE’:‘redis’})放到函数外,作为全局变量
2.装饰器缓存,timeout是缓存的生存时间,20秒内有缓存
3.缓存如果生效,第一次访问需要5秒,睡眠5秒,然后只要在缓存时间内的第二次以后的访问都不需要睡眠5秒。

(5)基本使用

需求:如果你是第一次访问,那么显示欢迎来到我的博客,如果你是第二次访问,那么显示爬虫快走开。

@blue.route('/testCache1/')
def testCache1():
   #cache.get(key)获取
    value = cache.get('ip')

    if value:
        return '爬虫快走开'
    else:
        #如果没有拿到这个value的时候,就在缓存中设置一下
        #等下一次访问就可以拿到了
        ip = request.remote_addr
        #cache.set(key value)设置的意思
        cache.set('ip', ip, timeout=10)
        return '欢迎来到我的博客'

运行结果:
第一次访问:
在这里插入图片描述
第二次访问:
在这里插入图片描述

二.钩子

现连接数据库进行增删改查,一般我们会如下操作:

@blue.route('/add/')
def add():
    print('连接数据库')
    return 'add'

@blue.route('/delete/')
def delete():
    print('连接数据库')
    return 'delete'

@blue.route('/update/')
def update():
    print('连接数据库')
    return 'update'

@blue.route('/find/')
def find():
    print('连接数据库')
    return 'find'

通过上面的代码,我们发现代码冗余,并没有实现解耦合,add、delete、update、find,它们每一个动作都是做自己的事 和连接数据库没有任何的关系。
这时,有人可能会想到将其封装,如下:

def getConn():
    print('连接数据库')

@blue.route('/add/')
def add():
    getConn()
    return 'add'

@blue.route('/delete/')
def delete():
    getConn()
    return 'delete'

@blue.route('/update/')
def update():
    getConn()
    return 'update'

@blue.route('/find/')
def find():
    getConn()
    return 'find'

如果将4个方法中公用的逻辑封装方法,那么也不是很好,因为耦合度同样很高,我们这种治标不治本,只不过看似代码减少。
解决方案:在执行视图函数之前,就执行某个方法
例如:如果我们能够在执行add、delete、update、find视图函数之前就执行某个方法而且这些方法还不会再add、delete、update、find中体现,那么耦合度是不是降到了最低。
blue.before_request就是在执行视图函数之前执行的方法
钩子的用法体现了一种思想,面向切面编程,也叫做面向方面编程(AOP)

代码都是一行一行的从上到下的执行,面对对象开发都是纵向开发,钩子这种方式实现了横向的开发,我们把这种方式叫做面向切面编程(AOP)

如果我们定义了@blue.before_request,那么所有的视图函数执行之前都会执行before_request。

@blue.route('/add/')
def add():
    print('==================')
    return 'add'

@blue.route('/delete/')
def delete():
    return 'delete'

@blue.route('/update/')
def update():
    return 'update'

@blue.route('/find/')
def find():
    return 'find'

@blue.before_request
def conn():
    print('连接数据库')

运行结果:
在这里插入图片描述
在这里插入图片描述

那么我们如何过滤请求?如下:

@blue.before_request
def conn():
    REQ_LIST = ['/add/','/delete/','/update/', '/find/']
    if request.path in REQ_LIST:
        print('连接数据库')

运行结果:
在这里插入图片描述

有在执行函数之前执行的方法,自然有在执行函数之后执行的方法。

@blue.after_request
def testClose(a):
    print('关闭连接')
    return a

运行结果:
在这里插入图片描述

三.四大内置对象

不需要创建就可以直接使用的对象

1.request和session

request和session我们之前写到过,这里就不说了,详情请看我之前的博文:Flask的Request、Response以及异常Flask的会话技术:cookie、session以及session持久化问题

2.config

可以用来查看当前项目的配置信息,可以在模板中直接使用
在视图函数中:

@blue.route('/testConfig/')
def testConfig():
    for c in current_app.config:
        print(c)
    return render_template('testConfig.html')

创建testConfig.html文件:

<body>
    <ul>
        {% for c  in config %}
            <li>{{ c }}</li>
        {% endfor %}
    </ul>
</body>

运行结果:
在这里插入图片描述

3.g

g:global(全局),可以帮助开发者实现跨函数传递数据

@blue.route('/g/')
def g():
    ip = request.remote_addr
    return '测试g'

思考:ip变量如何能在testg中使用?

@blue.route('/testg/')
def testg():
    return 'testg'

这时我们可以使用内置对象g:

@blue.route('/g/')
def g():
    g.ip = request.remote_addr
    return '测试g'

@blue.route('/testg/')
def testg():
    print('================')
    print(g.ip)
    print('================')
    return 'testg'

如果先运行testg,则会出现以下情况:
在这里插入图片描述

所以必须要在使用的那个视图函数之前使用,先运行g再运行testg:
在这里插入图片描述在这里插入图片描述

四.模板和static的路径问题

创建视图函数testRoute:

@blue.route('/testRoute/')
def testRoute():
    return render_template('testRoute.html')

创建testRoute.html模板:

<body>
    今天天气真好,适合爬山
</body>

运行结果:
在这里插入图片描述

思考:如果我们将static和templates拿出App文件夹,与App同级,是否能正常运行?
在这里插入图片描述

运行结果:
在这里插入图片描述

由上可知,路径出现错误,这时就需要在init文件中添加:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

template_folder = os.path.join(BASE_DIR,'templates')
static_folder = os.path.join(BASE_DIR,'static')
app = Flask(__name__,template_folder=template_folder,static_folder=static_folder)

保存上传,即可运行成功。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值