如何在Django的etag_func和last_modified_func中获取类视图self变量
解决方案
方案1:将回调函数改为类内部方法(最常用)
Django的condition装饰器支持传入字符串格式的方法名,会自动在视图实例上查找对应方法调用,此时方法第一个参数就是类实例self,可以直接访问queryset:
from django.db import models import hashlib class ProductsListAPIView(ListAPIView): queryset = Product.objects.active() serializer_class = ProductSerializer def my_last_modified(self, request, *args, **kwargs): # 直接通过self访问queryset,推荐用get_queryset()兼容动态查询集场景 return self.get_queryset().aggregate(latest=models.Max('updated_at'))['latest'] def get_etag_key(self, request, *args, **kwargs): product_ids = list(self.get_queryset().values_list('id', 'updated_at')) return hashlib.md5(str(product_ids).encode()).hexdigest() # 装饰器传入方法名字符串即可 @condition(etag_func='get_etag_key', last_modified_func='my_last_modified') def get(self, *args, **kwargs): return super().get(*args, **kwargs)
方案2:保持全局函数,调整参数顺序
如果你需要让这两个回调函数复用在多个视图中,可以保持全局定义,只需要给函数第一个参数加self接收视图实例即可:
import hashlib from django.db import models # 全局函数第一个参数加self接收视图实例 def my_last_modified(self, request, *args, **kwargs): return self.get_queryset().aggregate(latest=models.Max('updated_at'))['latest'] def get_etag_key(self, request, *args, **kwargs): product_ids = list(self.get_queryset().values_list('id', 'updated_at')) return hashlib.md5(str(product_ids).encode()).hexdigest() class ProductsListAPIView(ListAPIView): queryset = Product.objects.active() serializer_class = ProductSerializer # 直接传入函数引用即可 @condition(etag_func=get_etag_key, last_modified_func=my_last_modified) def get(self, *args, **kwargs): return super().get(*args, **kwargs)
注意事项
- 如果你的视图重写了
get_queryset方法实现动态过滤、权限校验等逻辑,优先调用self.get_queryset()获取查询集,不要直接访问self.queryset,避免拿到类定义阶段的静态查询集 - 计算etag时建议把更新时间也加入哈希计算,避免内容修改后etag不变的问题
内容的提问来源于stack exchange,提问作者LearnToday
相关产品推荐
相关产品推荐

