缓存 分页 中间件

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">&laquo;</span>
          </a>
        </li>
      {% else %}
        <li>
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</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">&raquo;</span>
          </a>
        </li>
        {#      {% else %}#}
        {#        <li>#}
        {#          <a href="#" aria-label="Next">#}
        {#            <span aria-hidden="true">&raquo;</span>#}
        {#          </a>#}
        {#        </li>#}
      {% endif %}


    </ul>
  </nav>


{% endblock %}
IMG_0687.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容