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

如何缓存Django Admin自动生成路由的SQL查询结果?

实现Django Admin自动生成路由的SQL查询缓存到Redis

当然可以实现这类自动生成路由的缓存,下面是几种实用的方案,适配你已经在使用的自定义AdminSite场景:

方法一:重写CustomAdminSite的get_urls方法

Django Admin的自动路由由AdminSite.get_urls()生成,你可以直接在自定义AdminSite里重写这个方法,给自动生成的视图批量加上缓存装饰器:

from django.contrib.admin import AdminSite
from django.views.decorators.cache import cache_page

class CustomAdminSite(AdminSite):
    def get_urls(self):
        # 先获取原生Admin生成的所有路由
        original_urls = super().get_urls()
        cached_urls = []
        
        for url in original_urls:
            # 识别自动生成的ModelAdmin视图(排除自定义URL)
            if hasattr(url.callback, '__module__') and url.callback.__module__.startswith('django.contrib.admin.options'):
                # 给视图添加Redis缓存,这里设置缓存时长为60秒,可按需调整
                cached_view = cache_page(60)(url.callback)
                # 替换原视图为带缓存的版本
                url = url._replace(callback=cached_view)
            cached_urls.append(url)
        
        return cached_urls

之后你依然用这个CustomAdminSite注册ModelAdmin即可,所有自动生成的列表页、编辑页等路由都会带上缓存。

方法二:针对单个ModelAdmin单独加缓存

如果不需要全局缓存,只想给特定Model的Admin页面加缓存,可以直接重写ModelAdmin的视图方法:

from django.contrib.admin import ModelAdmin
from django.views.decorators.cache import cache_page

class YourModelAdmin(ModelAdmin):
    # 给列表页加缓存
    def changelist_view(self, request, extra_context=None):
        cached_view = cache_page(60)(super().changelist_view)
        return cached_view(request, extra_context)
    
    # 编辑页缓存需谨慎,若页面包含用户专属数据,建议结合用户ID生成缓存键
    def change_view(self, request, object_id, extra_context=None):
        # 用用户ID做缓存键前缀,避免不同用户看到相同缓存内容
        cached_view = cache_page(60, key_prefix=f"admin_{request.user.id}")(super().change_view)
        return cached_view(request, object_id, extra_context)

方法三:用中间件针对性缓存Admin路由

如果想更灵活地控制哪些Admin路径缓存、哪些不缓存,可以自定义缓存中间件:

from django.utils.deprecation import MiddlewareMixin
from django.views.decorators.cache import cache_page

class AdminCacheMiddleware(MiddlewareMixin):
    def process_view(self, request, view_func, view_args, view_kwargs):
        # 只处理Admin开头的路径
        if request.path.startswith('/admin/'):
            # 排除登录、登出、密码修改等敏感路径
            exclude_paths = ['/admin/login/', '/admin/logout/', '/admin/password_change/']
            if not any(request.path.startswith(p) for p in exclude_paths):
                # 应用缓存
                return cache_page(60)(view_func)(request, *view_args, **view_kwargs)
        return None

然后在settings.py的MIDDLEWARE列表中添加这个中间件(注意顺序,建议放在靠近视图处理的位置):

MIDDLEWARE = [
    # 其他中间件...
    'your_app.middleware.AdminCacheMiddleware',
]

关键注意事项

  • 缓存时长根据业务需求调整,避免缓存过期不及时导致数据不一致。
  • 带权限控制的页面,一定要用key_prefix结合用户ID、权限组等生成唯一缓存键,防止用户越权看到其他用户的缓存内容。
  • 用Django Debug Toolbar验证时,注意观察页面请求的缓存命中状态,以及SQL查询是否被缓存替代。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:45:32