flask-cache的使用
1. 安装 pip install flask-caching
2. 初始化 cache = Cache(config={'CACHE_TYPE':'redis'}) cache.init_app(app=app)
缓存视图函数
def make_cache_key():
return request.url
@demo.route('/paginatestudent/')
@cache.cached(timeout=10, key_prefix=make_cache_key)
def paginate_student():
print('请求数据了')
page_num = int(request.args['page_num'])
per_page = 5
pagination = Student.query.paginate(page=page_num, per_page=per_page)
return render_template('index.html', pagination=pagination)
缓存数据
def get_all_students():
# 一上来就从缓存里查找,看有没有数据
students = cache.get('students')
# 如果缓存里没有数据,查询数据库,并且把查询到的结果写入到缓存里
if not students:
print('没有缓存数据,查询数据库')
students = Student.query.all()
cache.set('students', students, timeout=10)
return render_template('ShowStudents.html', students=students)
init.py
from flask import Flask
from App.ext import init_ext
from App.settings import Config
from App.views.demo import demo
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
init_ext(app=app)
app.register_blueprint(blueprint=demo)
return app
ext.py
from flask_bootstrap import Bootstrap
from flask_cache import Cache
from flask_debugtoolbar import DebugToolbarExtension
from flask_session import Session
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = SQLAlchemy()
cache = Cache(config={'CACHE_TYPE': 'redis'})
def init_ext(app):
Session(app)
db.init_app(app=app)
migrate = Migrate(app=app, db=db)
Bootstrap(app)
toolbar = DebugToolbarExtension(app)
cache.init_app(app=app)
settings.py
class Config:
SESSION_TYPE = 'redis'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:abcd1234@127.0.0.1:3306/day04'
SQLALCHEMY_TRACK_MODIFICATIONS = False
DEBUG = False # 如果要使用Flask-DebugToolbar需要打开DEBUG开关
SECRET_KEY = '23o43iokfjljhotjoJfojtg' # Flask-DebugToolbar必须要配置SECRET_KEY
manager.py
from flask_migrate import MigrateCommand
from flask_script import Manager
from App import create_app
app = create_app()
manager = Manager(app)
manager.add_command('db',MigrateCommand)
if __name__ == '__main__':
manager.run()
models.py
from App.ext import db
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
s_name = db.Column(db.String(16), nullable=False)
s_age = db.Column(db.Integer, nullable=False, default=10)
s_score = db.Column(db.Float, nullable=False, default=0)
views.py
import random
import time
from flask import Blueprint, render_template, request, current_app, g, abort
from App.ext import db, cache
from App.models import Student
demo = Blueprint('demo', __name__)
@demo.route('/')
def index():
return render_template('index.html')
@demo.route('/addstudents/')
def add_studnets():
students = []
for i in range(20):
student = Student()
num = random.randrange(20, 40)
student.s_name = '张三%d' % num
student.s_age = num
student.s_score = num * 2
students.append(student)
db.session.add_all(students)
db.session.commit()
return '批量添加成功'
@demo.route('/testglobal/')
def test_global():
# 在代码里如果要获取配置项,需要使用current_app拿到app对象,然后再获取config
# print(current_app.config)
# global test_flag
value = request.args['test_flag']
# test_flag = value
g.test_flag = value
if value == '200':
time.sleep(10)
print('睡会儿')
return g.test_flag
# test_flag = '100'
def make_cache_key():
page_num = request.args['page_num']
return request.remote_addr + 'page_num=' + page_num
@demo.route('/paginatestudent/')
@cache.cached(timeout=10, key_prefix=make_cache_key)
def paginate_student():
print('请求数据了')
page_num = int(request.args['page_num'])
per_page = 5
pagination = Student.query.paginate(page=page_num, per_page=per_page)
# students = pagination.items
# print(pagination.pages)
return render_template('index.html', pagination=pagination)
@demo.route('/getallstudents/')
def get_all_students():
# 一上来就从缓存里查找,看有没有数据
students = cache.get('students')
# 如果缓存里没有数据,查询数据库,并且把查询到的结果写入到缓存里
if not students:
print('没有缓存数据,查询数据库')
students = Student.query.all()
cache.set('students', students, timeout=10)
return render_template('ShowStudents.html', students=students)
@demo.before_request
def handle_before():
# print('请求之前')
# 先从缓存里查询次数
count = cache.get('count') or 1
# 如果次数大于10,直接不让用户再继续了
if count >= 10:
# return '5秒钟以内只能刷新十次'
abort(404)
count += 1
cache.set('count', count, timeout=5)
print(type(request.user_agent))
print(request.user_agent)
if not request.user_agent:
return '爬虫别爬了'
index.html
{% extends '/bootstrap/base.html' %}
{% block navbar %}
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="jumbotron">
<div class="container">
<h1>Hello, world!</h1>
<h1>欢迎来到王者荣耀</h1>
<p>敌军还有五秒到达战场,请做好准备</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
</div>
{% endblock %}
{% block content %}
<nav aria-label="Page nnavigation">
<ul>
{% for student in pagination.items %}
<li>id:{{ student.id }} 姓名:{{ student.s_name }} 年龄:{{ student.s_age }} 成绩:{{ student.s_score }}</li>
{% endfor %}
</ul>
{# 下面显示的页码 #}
<ul class="pagination">
{# 如果有上一页 #}
{% if pagination.has_prev %}
<li>
<a href="{{ url_for('demo.paginate_student') }}?page_num={{ pagination.prev_num }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{# 不推荐下面的写法#}
{# {% for page in range(pagination.pages) %}#}
{# <li><a href="#">{{ page + 1 }}</a></li>#}
{# {% endfor %}#}
{% for page in pagination.iter_pages() %}
{% if page %}
{# 如果现在选择的不是当前页 #}
{% if page != pagination.page %}
<li><a href=" {{ url_for('demo.paginate_student') }}?page_num={{ page }} ">{{ page }}</a></li>
{% else %}
<li class='active'><a href="#">{{ page }}</a></li>
{% endif %}
{% else %}
<span class=ellipsis>…</span>
{% endif %}
{% endfor %}
{% if pagination.has_next %}
<li>
<a href="{{ url_for('demo.paginate_student') }}?page_num={{ pagination.next_num }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{# {% else %}#}
{# <li>#}
{# <a href="#" aria-label="Next">#}
{# <span aria-hidden="true">»</span>#}
{# </a>#}
{# </li>#}
{% endif %}
</ul>
</nav>
{% endblock %}