如何为Djoser的URL添加Django REST framework的cache_page缓存
问题
我在Django REST framework中使用cache_page装饰器实现API缓存,认证环节采用Djoser配合DRF,但不清楚如何为Djoser的URL添加cache_page装饰器。
我的自定义视图集缓存实现示例:
class TagViewSet(viewsets.ModelViewSet): queryset=Tags.objects.all() serializer_class=TagSerializer permission_classes=[permissions.IsAuthenticated] authentication_classes= [authentication.TokenAuthentication] # 缓存配置 @method_decorator(cache_page(30)) def dispatch(self, *args, **kwargs): return super(TagViewSet, self).dispatch(*args, **kwargs)
我希望对Djoser的URL做完全相同的缓存处理,但我没有自定义的UserViewSet,也不知道如何访问Djoser自带的视图。我的users应用views.py为空,urls.py代码如下:
from django.urls import path, include from .views import * app_name='users' urlpatterns = [ path('api/auth/', include('djoser.urls')), path('api/auth/', include('djoser.urls.authtoken')), ]
解决方案
方法一:通过URL配置直接装饰Djoser视图
Django允许在URL配置中为包含的视图添加装饰器,你可以直接用django.views.decorators.cache.cache_page包装Djoser的URL规则:
修改users应用的urls.py:
from django.urls import path, include from django.views.decorators.cache import cache_page from djoser import urls as djoser_urls from djoser.urls import authtoken as djoser_authtoken_urls app_name='users' # 为所有Djoser基础URL添加30秒缓存 cached_djoser_urls = [ path('', include((cache_page(30)(urlconf) for urlconf in djoser_urls.urlpatterns), namespace='djoser')), ] # 按需为Token相关URL添加缓存(注意:登录/登出接口不建议缓存) cached_authtoken_urls = [ path('', include((cache_page(30)(urlconf) for urlconf in djoser_authtoken_urls.urlpatterns), namespace='djoser_authtoken')), ] urlpatterns = [ path('api/auth/', include(cached_djoser_urls)), path('api/auth/', include(cached_authtoken_urls)), ]
方法二:自定义Djoser视图集并添加缓存装饰器
如果需要更精细的缓存控制(比如只给部分接口加缓存),可以继承Djoser的视图类,添加缓存装饰器后重新配置URL:
- 在users应用的views.py中编写自定义视图:
from djoser.views import UserViewSet, TokenCreateView, TokenDestroyView from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page class CachedUserViewSet(UserViewSet): @method_decorator(cache_page(30)) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs) # 若不需要缓存Token接口,可跳过以下两个类 class CachedTokenCreateView(TokenCreateView): @method_decorator(cache_page(30)) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs) class CachedTokenDestroyView(TokenDestroyView): @method_decorator(cache_page(30)) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs)
- 修改users应用的urls.py,替换为自定义缓存视图:
from django.urls import path, include from .views import CachedUserViewSet, CachedTokenCreateView, CachedTokenDestroyView app_name='users' urlpatterns = [ # 用户相关URL,替换为缓存视图 path('api/auth/', [ path('users/', CachedUserViewSet.as_view({'get': 'list', 'post': 'create'}), name='user-list'), path('users/me/', CachedUserViewSet.as_view({'get': 'me', 'put': 'me', 'patch': 'me', 'delete': 'me'}), name='user-me'), path('users/<int:pk>/', CachedUserViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}), name='user-detail'), # 保留Djoser其他默认URL(如密码重置等) path('', include('djoser.urls.base')), ]), # Token相关URL(按需使用缓存视图) path('api/auth/', [ path('token/login/', CachedTokenCreateView.as_view(), name='token-create'), path('token/logout/', CachedTokenDestroyView.as_view(), name='token-destroy'), ]), ]
关键注意事项
- 避免缓存状态敏感接口:登录、登出、密码修改这类涉及用户状态变更的接口,缓存会导致逻辑错误,建议只缓存用户信息查询类接口(如
/users/me/、用户列表)。 - 合理设置缓存时长:根据业务数据更新频率调整缓存时间,防止缓存过期不及时导致数据不一致。
内容的提问来源于stack exchange,提问作者Abdullah Roshan
相关产品推荐
相关产品推荐

