让django-mptt与django-reversion玩得很好

时间:2014-08-08 20:57:10

标签: django django-mptt django-reversion

我正在开发一个项目,该项目使用django-reversion来跟踪变化并提供恢复到早期状态的能力,以及django-mptt用于某些树形模型。但是,删除和还原功能有一些时髦的行为。我正在使用看起来像这样的演示数据:

Big Company
    Sub Company 1
    Sub Company 2
      Tiny Company 1
      Tiny Company 2

我已经装配了django-reversion,因此删除节点将其所有子节点保存到修订版中 - 因此,删除Big Company会删除整个树,然后将其还原(或者,实际上,任何子节点)也会还原整个树。到目前为止,非常好。

然而,当我尝试删除/恢复子节点时,事情开始变得奇怪了。例如,删除子公司1'原因'子公司2'并且它的后代停止在模板中渲染(尽管这种行为是奇怪的,有点不一致)。或者,我应该使用django-reversion来恢复子公司2'删除后,“小公司”和“小公司”都没有删除。将在模板中呈现(尽管快速进入shell并调用对象显示它们仍然在数据库中,并且他们仍然拥有“Sub Company 2'作为其父级。” >

所有这些问题都可以通过调用Company.objects.rebuild()来修复,它将树恢复到正确的位置 - 但是这个项目的生产就绪版本可以有一个批次的数据数据库,因为这是一个整表活动,所以它会非常昂贵。关于我可以做些什么来解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:2)

好吧,我找到了一种让它发挥作用的方法。我不是简单地删除MPTT节点,而是将其移动到新的根位置。这会以简单地删除节点的方式正确地重新组织树。当然,我希望能够在之后重新附加节点,因此我将父主键存储在补充修订元数据选项中。相关代码如下所示:

class MPTT_Parent(models.Model):
    revision = models.OneToOneField(Revision)
    parent_id = models.IntegerField()

def remove_company(obj):
    with transaction.atomic() and reversion.create_revision():

         #These lines are to preserve the integrity of the tree before deleting it
         #Objects deleted from django-mptt trees don't automatically update the positions
        if not obj.is_root_node():
            reversion.add_meta(MPTT_Parent,parent_id=obj.parent.id)
        obj.move_to(target=None,position='first-child')

        obj.save()

        #Save all associated descendant information into the revision
        for child in obj.get_descendants(include_self=False):
            child.save()

   obj.delete()

def restore_company(version):
    #get the parent id.  If the parent has been deleted or was never set, 
    #keeps the node as root
    company = revert_object(version) #custom function that reverts given object
    try:
         parent = Company.objects.get(id=version.revision.mptt_parent.parent_id)
    except (ObjectDoesNotExist, AttributeError):
         pass
    else:
         company.move_to(target=parent,position='first-child')

    return company