Django自定义保存方法和更新

时间:2014-04-09 20:02:00

标签: python django django-queryset

我有自定义save()方法来检查我的对象"活跃" field等于2,然后为所有后代字段赋予相同的数字(使用MPTT

def save(self):
  if self.active == 2:
  self.get_descendants().update(active=2)

  super(Post, self).save()

现在,当我更新()我的模型时,我也想要这个代码工作。我应该尝试制作自定义更新方法吗?怎么做?

1 个答案:

答案 0 :(得分:1)

一个简单的解决方法是执行原始更新,然后使用get_queryset_descendants()为所有后代执行其他更新。完整代码是这样的:

qs = <some queryset>
qs.update(**values)
descendants = MyModel.objects.get_queryset_descendants(qs.filter(active=2))
descendants.update(active=2)

或者如果您只想更新active属性,可以一次性完成:

qs = <some queryset>
descendants = MyModel.objects.get_querset_descendants(qs, include_self=True)
descendants.update(active=2)

这当然可以包含在update函数中。这看起来像这样:

from django.db import transaction
from django.db.models.query import QuerySet

class MyModelQuerySet(QuerySet):
    def update(self, **kwargs):
        with transaction.atomic(): # for Django >= 1.6
        ####### OR ######
        with transaction.commit_on_succes(): # for Django <= 1.5
            r = super(MyModelQuerySet, self).update(**kwargs)
            descendants = self.model.objects.get_query_set_descendants(self.filter(active=2))
            descendants.update(active=2)
        return r

如果第二次更新失败,with transaction.atomic()with transaction.commit_on_succes()会阻止第一次更新保存,这是为了确保在第二次更新中出现问题时数据库级别的完整性。

您应该查看当前版本的Django的文档,了解如何将自定义查询集与自定义管理器一起使用(即mppt.managers.TreeManager)。