如何缓存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
相关产品推荐
相关产品推荐

