一、缓存基础与环境准备

什么是缓存?

缓存是指保存计算密集型操作的结果,当再次需要该结果时直接从缓存中获取,而无需重新计算。在 Django 中,缓存可以应用于不同粒度:

  • 整个网站缓存
  • 特定视图缓存
  • 页面片段缓存
  • 任意 Python 对象缓存

安装Redis

Django 支持多种缓存后端,其中 Redis 因其高性能和丰富的特性成为常用选择。

  • 安装Redis:过程略
  • 安装 Redis 客户端
pip install redis

Redis 缓存配置

在 Django 项目的settings.py文件中,通过CACHES配置项设置 Redis 缓存后端。

  • TIMEOUT:默认缓存超时时间(秒),默认为 300 秒(5 分钟)
  • OPTIONS:传递给缓存后端的选项
  • KEY_PREFIX:所有缓存键的前缀字符串
  • VERSION:缓存键的默认版本号
  • KEY_FUNCTION:定义缓存键生成规则的函数路径
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://password@127.0.0.1:6379",
"OPTIONS": {
"db": 0,
},
"KEY_PREFIX": "mars_framework", # 缓存前缀
"TIMEOUT": 60 * 60 * 12, # 缓存过期时间,单位为秒
}
}

二、缓存使用策略

站点缓存(不常用)

缓存整个站点是最简单的缓存方式,适用于内容不常变化的网站。配置方式如下(在settings.pyMIDDLEWARE中添加缓存中间件)

MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware', # 放在最前面
# 其他中间件...
'django.middleware.cache.FetchFromCacheMiddleware', # 放在最后面
]

视图缓存

针对特定视图进行缓存是更灵活的方式,适用于不同视图有不同更新频率的场景。

使用装饰器缓存视图

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # 缓存15分钟
def my_view(request):
# 视图逻辑...

视图缓存的特点

  • 以 URL 为缓存键,不同 URL 指向同一视图会分别缓存
  • 示例:/foo/1//foo/23/会被分别缓存
urlpatterns = [
path("foo/<int:code>/", my_view),
]

自定义缓存前缀:可以为不同视图设置不同的缓存前缀

@cache_page(60 * 15, key_prefix="site1")
def my_view(request):
...

在 URLconf 中配置缓存

from django.views.decorators.cache import cache_page

urlpatterns = [
path("foo/<int:code>/", cache_page(60 * 15)(my_view)),
]

三、缓存API详解

当需要更精细的缓存控制时,可以使用 Django 提供的缓存 API,直接操作缓存中的数据。

导入缓存模块

from django.core.cache import cache

基本操作

设置缓存

# 语法:cache.set(key, value, timeout=默认超时, version=None)
cache.set('my_key', 'hello, world!', 30) # 缓存30秒

获取缓存

# 语法:cache.get(key, default=None, version=None)
value = cache.get('my_key') # 获取缓存值,如果不存在返回None
value = cache.get('my_key', 'default_value') # 指定默认值

新增缓存(仅当键不存在时)

# 如果键不存在则添加,返回布尔值表示是否成功
success = cache.add("add_key", "Initial value")

获取或设置缓存

# 如果键存在则获取,否则设置并返回默认值
value = cache.get_or_set("my_new_key", "my new value", 100)

删除缓存

# 删除指定键,返回布尔值表示是否成功
success = cache.delete("a")

更新缓存过期时间

# 为已有键设置新的过期时间
success = cache.touch("a", 10) # 新超时时间10秒

四、缓存实战

场景说明

RBAC(Role-Based Access Control,基于角色的访问控制)是一种广泛使用的权限管理模型。在 Django+Vue 实现的后台管理系统中,一般采用RBAC权限策略。使用缓存机制,避免重复计算用户权限标识集合

写入缓存

用户成功登录后,前端自动调用获取登录用户的权限信息接口,获取登录用户的权限信息,包括

  • 用户基本信息 user
  • 用户角色集合 roles
  • 用户权限标识集合 permissions
  • 用户树状菜单集合 menus

将计算后的上述权限信息,写入Redis缓存。同时返回给前端,生成动态菜单。

@extend_schema(tags=["管理后台-system-认证"])
class AuthViewSet(viewsets.GenericViewSet):
serializer_class = AuthLoginSerializer
queryset = SystemUsers.objects.none() @extend_schema(summary="获取登录用户的权限信息")
@action(methods=["get"], detail=False, url_path="get-permission-info")
def get_permission_info(self, request, *args, **kwargs):
"""获取登录用户的权限信息"""
user_id = request.user.id
cache_key = f"system_users_{user_id}"
user = SystemUsers.objects.prefetch_related("roles", "roles__menus").get(
id=user_id
)
serializer = AuthPermissionInfoSerializer(user, context={"request": request})
cache.set(cache_key, serializer.data, timeout=None)
return CommonResponse.success(data=serializer.data)

读取缓存

用户执行某个API接口时,会进行权限判断。后端权限判断时,会从缓存中读取当前请求用户的权限标识集合,然后对比本次请求的权限标识(如 "system:post:query")。如果包含在集合中,则返回true,否则返回false

点击查看RBAC权限原理

删除缓存

当用户退出登录时,删除用户的缓存信息

    @extend_schema(summary="登出系统")
@action(
methods=["post"],
detail=False,
url_path="logout",
permission_classes=[AllowAny],
)
def logout(self, request, *args, **kwargs):
"""登出系统"""
cache.delete(f"system_users_{request.user.id}") # 清空用户Redis
# ...

点击查看完整代码


您正在阅读的是《Django从入门到实战》专栏!关注不迷路~

Django缓存机制详解:从配置到实战应用的更多相关文章

  1. PHP缓存机制详解

    一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...

  2. 二,PHP缓存机制详解

    一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...

  3. hibernate缓存机制详解

    hiberante面试题—hibernate缓存机制详解   这是面试中经常问到的一个问题,可以按照我的思路回答,准你回答得很完美.首先说下Hibernate缓存的作用(即为什么要用缓存机制),然后再 ...

  4. 浏览器 HTTP 协议缓存机制详解

    最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...

  5. nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解

    1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...

  6. 浏览器 HTTP 协议缓存机制详解--网络缓存决策机制流程图

    1.缓存的分类 2.浏览器缓存机制详解 2.1 HTML Meta标签控制缓存 2.2 HTTP头信息控制缓存 2.2.1 浏览器请求流程 2.2.2 几个重要概念解释 3.用户行为与缓存 4.Ref ...

  7. RecyclerView 缓存机制详解

    一 前言 RecyclerView据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView.GridView.RecyclerView可以用来代替传 ...

  8. IOS缓存机制详解

    资料均来自互联网,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. 人魔七七:http://www.cnblogs.com/qiqibo/ 为什么要有缓存 应用需要 ...

  9. 【转】IOS缓存机制详解

    人魔七七:http://www.cnblogs.com/qiqibo/ 为什么要有缓存 应用需要离线工作的主要原因就是改善应用所表现出的性能.将应用内容缓存起来就可以支持离线.我们可以用两种不同的缓存 ...

  10. MySQL缓存机制详解(一)

    本文章拿来学习用||参考资料:http://www.2cto.com/database/201308/236361.html 对MySql查询缓存及SQL Server过程缓存的理解及总结   一.M ...

随机推荐

  1. 一套基于 Bootstrap 和 .NET Blazor 的开源企业级组件库

    前言 今天大姚给大家分享一套基于 Bootstrap 和 .NET Blazor 的开源企业级组件库:Bootstrap Blazor. 项目介绍 BootstrapBlazor 是一套基于 Boot ...

  2. Python标准库学习之logging

    前言 在python程序中,出于调试监测或者追踪(track)的目的,一般会在关键的部位加print语句来输出监测的变量值,但对于复杂的程序来讲,这样的调试手段就远远不够了,这也是logging库存在 ...

  3. java初级笔记(翁恺男神

    一.基础 1.类型转换 两个整数的运算结果只能是整数(自动向下取整 自动类型转换(由低变高 强制类型转换(从高到低 2.运算符优先级 正负号>乘除取余>加减连接>关系运算符>赋 ...

  4. 极简版秒表(java GUI)

    package javaPractice; import javax.swing.*; import java.text.*; import java.util.*; import java.awt. ...

  5. .NET外挂系列:7. harmony在高级调试中的一些实战案例

    一:背景 1. 讲故事 如果你读完前六篇,我相信你对 harmony 的简单使用应该是没什么问题了,现在你处于手拿锤子看谁都是钉子的情况,那这篇我就找高级调试里非常经典的 3个钉子 让大家捶一锤. 二 ...

  6. .NET周刊【5月第2期 2025-05-11】

    国内文章 C#/.NET/.NET Core优秀项目和框架2025年4月简报 https://www.cnblogs.com/Can-daydayup/p/18865040 本文介绍了每月定期推荐的C ...

  7. DevOps 需要处理的工作

    本文纯属个人工作记录: 1.部署Linux服务器 2.安装Docker 3.在Docker中安装Gitlab和runner 4.设置Gitlab pipline,即CI/CD 5.可能需要Jenkin ...

  8. Biology 题解

    Biology 题解 题意简述 初始有\(n\)个字符串,有\(m\)个操作,操作分为两种: 插入一个新的字符串,下标递增(\(n+1,n+2,n+3\dots\)). 查询\(k\)个字符串\(x_ ...

  9. Web前端入门第 62 问:JavaScript 循环结构注意事项

    HELLO,这里是大熊的前端开发笔记. 循环作为 算法与数据结构 中的基石,JS 与其他编程语言一样,都提供了多种循环结构用于处理数据. for 循环 事物的开端往往都是从最常用的开始,循环结构咱们从 ...

  10. 揭秘C#异步编程核心机制:从状态机到线程池的全面拆解

    C#中的异步编程是一个强大且复杂的特性,它允许开发者编写非阻塞的代码,从而显著提升应用程序的响应性和吞吐量.本文将深入剖析异步编程的底层原理,从async和await关键字的工作机制,到状态机.任务调 ...