[Answered ]-Getting django-mptt to play nice with django-reversion

2👍

Well, I found a way to get this to work. Instead of simply deleting the MPTT node, I move it so that it’s in a new root position. This reorganizes the tree properly in a way that simply deleting the node doesn’t seem to. Of course, I’d like to be able to reattach the node after, so I store the parents primary key in a supplemental revision metadata option. Relevant code looks like this:

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

Leave a comment