天天看点

高阶应用-缓存

一、原因

对于一个中等流量网站,尽可能地减少开销是很有必要的。缓存数据就是为了保护那些需要很多计算资源的结果,这样就不必在下次重新消耗资源进行计算

二、缓存系统工作原理

对于给定的网址,尝试从缓存中找到网址,如果页面在缓存中,直接返回缓存的页面,如果缓存中没有,一系列操作(比如查数据库)后,保存生成的页面内容到缓存系统以供下一次使用,然后返回生成的页面内容

三、缓存的好处

  • 减轻服务器的压力
  • 提供良好的用户体验

四、缓存的方式

缓存在数据库中

配置settings.py

<span class="hljs-comment"># 添加缓存配置</span>
CACHES = {
    <span class="hljs-string">'default'</span>:{
        <span class="hljs-string">'BACKEND'</span>:<span class="hljs-string">'django.core.cache.backends.db.DatabaseCache'</span>,
        <span class="hljs-string">'LOCATION'</span>:<span class="hljs-string">'my_cache_table'</span>,
        <span class="hljs-string">'OPTIONS'</span>:{
            <span class="hljs-string">'MAX_ENTRIES'</span>:<span class="hljs-string">'10'</span>,  <span class="hljs-comment"># 缓存数据的最大条数 超出则自动清除</span>
        },
        <span class="hljs-string">'KEY_PREFIX'</span>:<span class="hljs-string">'cache'</span>, <span class="hljs-comment"># 缓存前缀</span>
    }
}
           

复制

生成缓存所需要的缓存表

python manage.py createcachetable [table_name]

python manage.py createcachetable my_cache_table

缓存在内存中

配置settings.py

<span class="hljs-comment"># 配置缓存在内存中</span>
CACHES = {
  <span class="hljs-string">'default'</span>:{
        <span class="hljs-string">'BACKEND'</span>:<span class="hljs-string">'django.core.cache.backends.locmem.LocMemCache'</span>,
    }
}
           

复制

缓存在文件中

CACHES = {
    <span class="hljs-string">'default'</span>:{
        <span class="hljs-string">'BACKEND'</span>:<span class="hljs-string">'django.core.cache.backends.filebased.FileBasedCache'</span>,
        <span class="hljs-string">'LOCATION'</span>:<span class="hljs-string">r'C:\Users\xlg\Desktop\cache'</span>,
    }
}
           

复制

缓存在redis中

安装第三方扩展库

pip install django-redis

配置

<span class="hljs-comment"># 缓存在redis中</span>
CACHES = {
    <span class="hljs-string">'default'</span>:{
        <span class="hljs-string">'BACKEND'</span>:<span class="hljs-string">'django_redis.cache.RedisCache'</span>,
        <span class="hljs-string">'LOCATION'</span>:<span class="hljs-string">'redis://127.0.0.1:6379/1'</span>
      
    }
}
           

复制

五、单个视图缓存

cache_page装饰器的参数:

  • time 秒 过期的时间
  • cache缓存配置 默认为default
  • key_prefix 缓存的前缀
<span class="hljs-keyword">from</span> django.views.decorators.cache <span class="hljs-keyword">import</span> cache_page

<span class="hljs-comment"># 缓存的使用</span>
<span class="hljs-meta">@cache_page(10)</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_filter</span><span class="hljs-params">(req)</span>:</span>
    print(<span class="hljs-string">'你能看到我几次'</span>)
    u = User.objects.all()
    <span class="hljs-keyword">return</span> render(req,<span class="hljs-string">'show_data.html'</span>,{<span class="hljs-string">'u'</span>:u})
           

复制

六、底层缓存API

导入

from django.core.cache import cache

缓存操作

  • 设置

    cache.set(key,value,expires)

  • 获取

    cache.get(key)

  • 删除

    cache.delete(key)

  • 清空

    cache.clear()

示例

<span class="hljs-keyword">from</span> django.core.cache <span class="hljs-keyword">import</span> cache
<span class="hljs-keyword">from</span> django.template <span class="hljs-keyword">import</span> loader

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">my_cache</span><span class="hljs-params">(req)</span>:</span>
    res = cache.get(<span class="hljs-string">'user'</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> res:
        u = User.objects.all()
        tem = loader.get_template(<span class="hljs-string">'show_user.html'</span>)
        res = tem.render({<span class="hljs-string">'u'</span>:u})
        cache.set(<span class="hljs-string">'user'</span>, res, <span class="hljs-number">60</span>)
    <span class="hljs-keyword">return</span> HttpResponse(res)
           

复制

七、缓存案例

settings.py配置

<span class="hljs-comment"># 缓存在redis中</span>
CACHES = {
    <span class="hljs-string">'default'</span>:{
        <span class="hljs-string">'BACKEND'</span>: <span class="hljs-string">'django_redis.cache.RedisCache'</span>,
        <span class="hljs-string">'LOCATION'</span>: <span class="hljs-string">'redis://127.0.0.1:6379/1'</span>,
    }
}
           

复制

视图函数

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">register</span><span class="hljs-params">(req)</span>:</span>
    <span class="hljs-keyword">if</span> req.method == <span class="hljs-string">'GET'</span>:
        <span class="hljs-keyword">return</span> render(req, <span class="hljs-string">'register.html'</span>)
    <span class="hljs-keyword">elif</span> req.method == <span class="hljs-string">'POST'</span>:
        username = req.POST.get(<span class="hljs-string">'username'</span>)
        userpass = req.POST.get(<span class="hljs-string">'userpass'</span>)
        email = req.POST.get(<span class="hljs-string">'email'</span>)
        <span class="hljs-keyword">if</span> cache.get(username):
            <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'该账户已存在'</span>)
        <span class="hljs-keyword">else</span>:
            <span class="hljs-comment"># 设置None为永远不过期</span>
            cache.set(username,userpass, <span class="hljs-keyword">None</span>)
    <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'成功'</span>)




<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">Login</span><span class="hljs-params">(req)</span>:</span>
    <span class="hljs-keyword">if</span> req.method == <span class="hljs-string">'GET'</span>:
        <span class="hljs-keyword">return</span> render(req, <span class="hljs-string">'login.html'</span>)
    <span class="hljs-keyword">elif</span> req.method == <span class="hljs-string">'POST'</span>:
        username = req.POST.get(<span class="hljs-string">'username'</span>)
        userpass = req.POST.get(<span class="hljs-string">'userpass'</span>)
        email = req.POST.get(<span class="hljs-string">'email'</span>)
        password = cache.get(username)
        <span class="hljs-keyword">if</span> password <span class="hljs-keyword">and</span> password == userpass:
            <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'登录成功'</span>)
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'请输入正确的用户名或密码'</span>)

           

复制

登录/注册模板

<!DOCTYPE html>
<html>
<head>
    <title>登录页面</title>
<style>
        .pg_header{
            position: fixed;
            height: 48px;
            top: 0;
            left: 0;
            right: 0;
            background-color: #2459a2;
            line-height: 48px;
        }
        .pg_header .logo{
            margin: 0 auto;
            float: left;
            width: 200px;
            text-align: center;
            line-height: 48px;
            font-size: 28px;
            color: white;
        }
        .pg_dl{
            left: 400px;
            display: inline-block;
            padding: 0 40px;
            color: white;
        }
        .pg_header .pg_dl:hover{
            background-color: #2459fb;
            cursor: pointer;
        }
        .left{
            margin-top: 20px;
            width: 400px;
            display: inline-block;
            float: left;
        }
        .pg_body{
            margin-top: 50px;
            font-size: 18px;
            display: inline-block;
            width: 200px;
        }
        .pg_body .menu{
            width: 800px;
            padding: 15px;
            float: left;
            font-weight: bold;
        }
        input[type="text"]{
            width: 200px;
            height: 25px;
            border-radius: 6px;
        }
        input[type="password"]{
            width: 200px;
            height: 25px;
            border-radius: 6px;
        }
        input[type="button"]{
            background-color: #555555;
               border: none;
            color: white;
            padding: 12px 29px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 17px;
            margin: 4px 2px;
            cursor: pointer;
            border-radius: 4px;
        }
        input[type="submit"]{
            background-color: #555555;
               border: none;
            color: white;
            padding: 12px 29px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 17px;
            margin: 4px 2px;
            cursor: pointer;
            border-radius: 4px;
        }
        .kong{
            margin-top: -54px;
            margin-left: 200px;
            float:left;
            padding: 15px;
        }
        .img{
            width: 50px;
            height: 40px;
        }
        .can{
            width: 1220px;
            height: 40px;
            line-height: 40px;
            margin: 0 auto;
            text-align: center;
            display: inline-block;
        }
        .tian{
            color: red;
            float: right;
            font-size: 12px;
            margin-right: -120px;
            margin-top: -25px;
        }
    </style>
</head>
<body id="i88" style="margin: 0">
    <div class = "pg_header">
        <a class = "logo">LOGO</a>
        <a class="pg_dl" id="i77">登录</a>
    </div>
    <form name="tijiao" method="post" onsubmit="return check()" action="{% url 'App:login' %}">
        {% csrf_token %}
        <div class="left"></div>
        <div class="pg_body">
                <div class="menu">用户名:</div>
                    <div class="kong">
                        <input id="text1" type="text" name="username" placeholder="请输入用户名"><span id="div1" class="tian" style="margin-top: 4px">*(为必填)</span>
                    </div>

                <div class="menu">密码:</div>
                    <div class="kong">
                        <input id="text2" type="password" name="userpass" onblur="check()">
                        <span id="div2" class="tian" style="margin-top: 5px">*(为必填)</span>
                    </div>

        </div>
        <div class="can">
            <input id="i111" type="submit" name="002" value="登  录">
            <p style="width: 200px;display: inline-block;"></p>
            <input id="i222" type="button" name="004" value="取  消">
        </div>
    </form>
</body>
</html>           

复制

路由地址

<span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path
<span class="hljs-keyword">from</span> App.views <span class="hljs-keyword">import</span> *

urlpatterns = [
    path(<span class="hljs-string">''</span>, main.index, name=<span class="hljs-string">'index'</span>),
    path(<span class="hljs-string">r'login/'</span>, main.Login, name=<span class="hljs-string">'login'</span>),
    path(<span class="hljs-string">r'register/'</span>, main.register, name=<span class="hljs-string">'register'</span>),
]
           

复制