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

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,提问作者איתי גיל

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:50:23