You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何预填充Django中使用cache_page装饰的DRF ViewSet接口缓存

实现方案

1. 配置数据库缓存

首先修改settings.py中的缓存配置,替换默认的LocMemCache为数据库缓存:

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.db.DatabaseCache",
        "LOCATION": "custom_cache_table", # 自定义缓存表名
        "TIMEOUT": 60 * 15, # 对应你原有的15分钟默认缓存超时
        "OPTIONS": {
            "MAX_ENTRIES": 1000, # 你只有1个缓存条目,随便设即可
        }
    }
}

配置完成后执行命令生成缓存表:

python manage.py createcachetable

2. 调整视图缓存逻辑(推荐手动缓存,比cache_page更易控制)

原有的cache_page装饰器缓存key和请求路径、请求头强绑定,手动更新时需要计算key比较麻烦,改成手动控制缓存key的逻辑更适合你的场景,修改后的视图代码如下:

from django.core.cache import cache

# 固定缓存key,方便后续预更新时直接调用
HOME_ARTICLE_CACHE_KEY = "home_article_list_data"

@action(detail=False)
def home(self, request) -> Response:
    # 优先从缓存取数据
    cache_data = cache.get(HOME_ARTICLE_CACHE_KEY)
    if cache_data:
        return Response(cache_data, headers={'Access-Control-Allow-Origin': '*'})
    # 缓存未命中时查库序列化
    articles = Article.objects.home()
    resp_data = serializers.ArticleListSerializer(articles, many=True).data
    # 写入缓存,超时时间15分钟
    cache.set(HOME_ARTICLE_CACHE_KEY, resp_data, settings.DEFAULT_CACHE_TIMEOUT)
    return Response(resp_data, headers={'Access-Control-Allow-Origin': '*'})

3. 编写自定义Management Command

在你的App目录下新建management/commands目录,目录内新增两个文件:

  • __init__.py(空文件即可)
  • update_home_article_cache.py,代码如下:
from django.core.management.base import BaseCommand
from django.core.cache import cache
from yourapp.models import Article
from yourapp import serializers
# 导入视图里定义的固定缓存key
from yourapp.views.article import HOME_ARTICLE_CACHE_KEY
from django.conf import settings

class Command(BaseCommand):
    help = "预更新首页文章列表缓存"

    def handle(self, *args, **options):
        # 生成最新的序列化数据
        articles = Article.objects.home()
        latest_data = serializers.ArticleListSerializer(articles, many=True).data
        # 写入缓存覆盖旧数据
        cache.set(HOME_ARTICLE_CACHE_KEY, latest_data, settings.DEFAULT_CACHE_TIMEOUT)
        self.stdout.write(self.style.SUCCESS("首页文章缓存预更新成功"))

注意把代码里的yourapp替换成你实际的App名称。

4. 配置Crontab定时任务

执行crontab -e添加定时任务,每5分钟执行一次缓存更新命令:

# 替换为你实际的虚拟环境路径和项目路径
*/5 * * * * /opt/your_project/venv/bin/python /opt/your_project/manage.py update_home_article_cache >> /var/log/update_cache.log 2>&1

注意事项

  • 缓存超时时间设为15分钟,定时每5分钟执行一次,就算单次定时任务执行失败,也有10分钟的缓冲时间,不会出现用户访问时缓存击穿的情况
  • 数据库缓存对于单条缓存条目性能完全足够,不会有额外负担
  • 如果坚持要使用原有的cache_page装饰器,可通过构造模拟请求对象调用视图,触发cache_page自动写入缓存,只是逻辑复杂度更高

内容的提问来源于stack exchange,提问作者Milano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:39:02