Django自定义视图中装饰器更新类属性失效问题排查与解决
Django多QuerySet视图的QuerySet刷新问题解决
场景背景
使用Django作为Web应用框架时,因同一视图需同时操作多个QuerySet与Serializer,自行实现了自定义ModelView并手动编写所有CRUD方法,初始代码如下:
class Models1AndModel2View(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): model1 = Model1.objects.all() model1_serializer_class = Model1Serializer model2 = Model2.objects.all() model2_serializer_class = Model2Serializer def refresh_querysets(func): def inner(self, *args, **kwargs): value = func(self, *args, **kwargs) self.model1 = Model1.objects.all() self.model2 = Model2.objects.all() return value return inner @refresh_querysets def list(self, request, *args, **kwargs): ... @refresh_querysets def retrieve(self, pk, request, *args, **kwargs): ... @refresh_querysets def update(self, pk, request, *args, **kwargs): ... @refresh_querysets def delete(self, pk, request, *args, **kwargs): ... @refresh_querysets def create(self, request, *args, **kwargs): ...
问题现象
为CRUD方法添加上述refresh_querysets装饰器后,发现更新的类属性未生效:
- 首次列出所有模型实例,共2个;
- 删除其中一个实例;
- 再次执行列表操作,
model1和model2仍显示2个实例; - 直接查询数据库模型可确认实例已删除,但视图的类属性未刷新。
解决思路
调整装饰器内代码执行顺序,先刷新QuerySet再执行目标方法,修改后的装饰器代码如下:
def refresh_querysets(func): def inner(self, *args, **kwargs): self.model1 = Model1.objects.all() self.model2 = Model2.objects.all() return func(self, *args, **kwargs) return inner
调整后,每次执行CRUD方法前都会重新获取最新的QuerySet,避免了旧缓存数据导致的显示错误。
内容的提问来源于stack exchange,提问作者איתי גיל
相关产品推荐
相关产品推荐

