每天40分玩转Django:Django缓存

一、Django缓存概述

在高并发的Web应用中,缓存是提高性能的重要手段。通过缓存频繁访问的数据,可以显著减少数据库查询和渲染模板的时间,从而加快响应速度,提升用户体验。Django提供了多层级的缓存方案,可以灵活地满足不同场景下的缓存需求。

Django支持的缓存方式包括:

  1. 视图缓存(Per-view cache):对视图函数的结果进行缓存
  2. 模板片段缓存(Template fragment cache):对模板中的一部分进行缓存
  3. 底层缓存API(Low-level cache API):提供了较低层级的缓存接口
  4. 基于会话的缓存(Session-based cache):利用会话机制实现的缓存

下图展示了Django多层级缓存结构:
Django 视图缓存 模板片段缓存 底层缓存API 基于会话的缓存

二、视图缓存

视图缓存是最常用的缓存方式,通过缓存视图函数的返回结果,可以避免重复执行耗时的逻辑和数据库查询。Django提供了方便的装饰器@cache_page来实现视图缓存。

  1. 使用@cache_page装饰器
    @cache_page装饰器接受一个参数timeout,表示缓存过期时间,单位为秒。例如:
python 复制代码
from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # 缓存15分钟
def my_view(request):
    # 视图逻辑
    return render(request, 'my_template.html', {'data': data})

上述代码对my_view视图函数的结果进行缓存,缓存时间为15分钟。在缓存有效期内,重复请求将直接返回缓存的结果,而不会执行视图函数。

  1. 缓存键的生成
    Django会根据请求的URL、请求方法、GET参数等信息自动生成缓存键。默认情况下,不同的请求参数会生成不同的缓存键。例如:
  • /foo/
  • /foo/?page=1
  • /foo/?page=2

这三个URL会生成不同的缓存结果。如果希望忽略GET参数,可以设置cache_pagekey_prefix参数:

python 复制代码
@cache_page(60 * 15, key_prefix='foo')
def my_view(request):
    pass

这样,不同的GET参数将使用相同的缓存键。

  1. 缓存储备
    视图缓存的结果默认存储在默认的缓存后端中。可以在settings.py中配置缓存后端:
python 复制代码
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}

上述配置使用Memcached作为缓存后端。Django支持多种缓存后端,如Redis、文件系统、数据库等。

  1. 示例代码
    下面是一个使用视图缓存的完整示例:
python 复制代码
# views.py
from django.shortcuts import render
from django.views.decorators.cache import cache_page
from .models import Article

@cache_page(60 * 15)
def article_list(request):
    articles = Article.objects.all()
    return render(request, 'article_list.html', {'articles': articles})
html 复制代码
<!-- article_list.html -->
{% for article in articles %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.content }}</p>
{% endfor %}

访问article_list视图时,将从数据库查询文章列表,并渲染模板。视图结果会被缓存15分钟,在此期间的重复请求将直接返回缓存内容。

下图展示了视图缓存的工作流程:

sequenceDiagram Client->>+Django: GET /article/list/ Django->>+Cache: 检查缓存 alt 缓存未命中 Cache-->>-Django: 无缓存 Django->>+Database: 查询数据 Database-->>-Django: 返回数据 Django->>Django: 渲染模板 Django->>Cache: 写入缓存 else 缓存命中 Cache-->>-Django: 返回缓存 end Django-->>-Client: 响应结果

三、基于会话的缓存

基于会话的缓存利用Django的会话(Session)机制实现缓存。它将缓存数据存储在会话中,每个用户都有独立的缓存空间。相比视图缓存,会话缓存更适合存储与用户相关的数据,如用户偏好设置、购物车等。

  1. 启用会话中间件
    要使用基于会话的缓存,需要确保启用了会话中间件。在settings.py中添加以下配置:
python 复制代码
MIDDLEWARE = [
    # 其他中间件
    'django.contrib.sessions.middleware.SessionMiddleware',
    # 其他中间件
]
  1. 使用会话缓存
    在视图函数中,可以通过request.session字典来读写会话数据。例如:
python 复制代码
def my_view(request):
    # 读取会话缓存
    value = request.session.get('my_key', 'default_value')
    
    # 写入会话缓存
    request.session['my_key'] = 'new_value'
    
    return HttpResponse(value)

上述代码从会话中读取键为'my_key'的值,如果不存在则使用默认值'default_value'。然后将'my_key'的值更新为'new_value'。

  1. 会话过期时间
    默认情况下,Django的会话过期时间为两周。可以通过SESSION_COOKIE_AGE设置来修改过期时间,单位为秒:
python 复制代码
SESSION_COOKIE_AGE = 60 * 60 * 24  # 会话有效期为1天
  1. 示例代码
    下面是一个使用基于会话的缓存的示例:
python 复制代码
# views.py
from django.shortcuts import render

def set_language(request):
    lang = request.GET.get('lang', 'en')
    request.session['language'] = lang
    return HttpResponse('Language set to ' + lang)

def index(request):
    lang = request.session.get('language', 'en')
    return render(request, 'index.html', {'language': lang})
html 复制代码
<!-- index.html -->
<p>Current language: {{ language }}</p>
<ul>
    <li><a href="{% url 'set_language' %}?lang=en">English</a></li>
    <li><a href="{% url 'set_language' %}?lang=zh">中文</a></li>
</ul>

在上述示例中,set_language视图从GET参数获取语言选项,并将其存储在会话中。index视图从会话中读取语言选项,并渲染模板。用户可以通过点击链接切换语言,选择的语言会保存在会话中,在后续请求中生效。

下图展示了基于会话缓存的工作流程:
Client Django GET /set_language/?lang=zh 将语言选项保存到会话 响应结果 GET /index/ 从会话读取语言选项 渲染模板 响应结果 Client Django

四、缓存的最佳实践

在使用Django缓存时,需要注意以下几点:

  1. 选择合适的缓存粒度。视图缓存适合缓存整个页面,而对于页面中的局部内容,可以使用模板片段缓存。

  2. 设置合理的缓存过期时间。过期时间太短会导致频繁的缓存失效,过期时间太长又会影响数据的实时性。需要根据具体业务需求权衡。

  3. 注意缓存数据的一致性。当数据发生变化时,要及时更新或清除相关的缓存,避免出现脏数据。

  4. 合理使用缓存键。对于不同的请求参数,要生成不同的缓存键,避免缓存结果互相覆盖。

  5. 监控缓存的命中率和性能指标,找出性能瓶颈,并进行优化。

小结

本文详细介绍了Django的视图缓存和基于会话的缓存,通过丰富的示例代码和流程图,帮助大家深入理解缓存的工作原理和使用方法。Django缓存是优化Web应用性能的利器,合理利用缓存可以显著提升响应速度和吞吐量。


怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

相关推荐
OceanBase数据库官方博客4 分钟前
向量检索+大语言模型,免费搭建基于专属知识库的 RAG 智能助手
人工智能·oceanbase·分布式数据库·向量数据库·rag
测试者家园4 分钟前
ChatGPT助力数据可视化与数据分析效率的提升(一)
软件测试·人工智能·信息可视化·chatgpt·数据挖掘·数据分析·用chatgpt做软件测试
西猫雷婶7 分钟前
python学opencv|读取图像(十九)使用cv2.rectangle()绘制矩形
开发语言·python·opencv
靖顺35 分钟前
【OceanBase 诊断调优】—— packet fly cost too much time 的根因分析
数据库·oceanbase
liuxin3344556636 分钟前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
海绵波波10740 分钟前
flask后端开发(10):问答平台项目结构搭建
后端·python·flask
赵谨言1 小时前
基于python网络爬虫的搜索引擎设计
爬虫·python·搜索引擎
code04号1 小时前
python脚本:批量提取excel数据
开发语言·python·excel
B1nna2 小时前
Redis学习(三)缓存
redis·学习·缓存