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

Django 4重写save()方法时查询未实时更新问题求助

Django 4重写save()方法时,多对多字段查询不实时更新的解决办法

为啥会出现这个问题?

Django为了减少数据库查询次数,会给模型实例的多对多关系查询结果做缓存。你第一次调用self.exercises.all()时,结果就存在实例的缓存里了,后面再调用all()直接取缓存的旧数据,不会重新去数据库查新的——哪怕父类的save方法已经修改了关联的练习数据。

怎么解决?

方法1:刷新实例缓存

在父类save之后,调用self.refresh_from_db(),强制从数据库重新加载整个实例的数据,包括多对多关联:

class Routine(models.Model):
    exercises = models.ManyToManyField(Exercise)

    def save(self, *args, **kwargs):
        e = self.exercises.all()  # 返回初始的3个练习
        super().save(*args, **kwargs)  # 父类方法修改关联练习
        self.refresh_from_db()  # 清空缓存,从数据库重新拉数据
        e = self.exercises.all()  # 现在拿到的就是更新后的练习列表

方法2:直接从数据库查最新数据

如果不想刷新整个实例,也可以绕过实例的缓存,直接通过模型管理器查询当前实例的最新关联数据:

class Routine(models.Model):
    exercises = models.ManyToManyField(Exercise)

    def save(self, *args, **kwargs):
        e = self.exercises.all()  # 返回初始的3个练习
        super().save(*args, **kwargs)  # 父类方法修改关联练习
        # 直接查数据库里当前实例的最新关联
        e = Routine.objects.get(pk=self.pk).exercises.all()

额外提醒

多对多的缓存是Django的性能优化手段,大部分时候能减少重复查询,但遇到这种需要在同一方法内获取更新后数据的场景,就得手动处理缓存问题。refresh_from_db()是通用解法,适合大多数情况,操作起来也简单。

内容的提问来源于stack exchange,提问作者Gonzalo Dambra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:30:09