Created
February 20, 2013 11:06
-
-
Save bartekbrak/4994828 to your computer and use it in GitHub Desktop.
rebuild mptt tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: UTF-8 -*- | |
from django.core.management.base import BaseCommand, CommandError | |
from cms.models.pagemodel import Page | |
from optparse import make_option | |
def rebuild_tree(parent, left=1, recursion_level=0, commit=False): | |
right = left + 1 | |
page = Page.objects.filter(id=parent).get() | |
# element header | |
print "%s(%02d) %s" % ('\t' * recursion_level, page.id, page.get_title()) | |
children = Page.objects.filter(parent=parent) | |
for child in children: | |
right = rebuild_tree(child.id, left=right, recursion_level=recursion_level + 1, commit=commit) | |
# element footer | |
print "%s%s-%s=>%s-%s " % ('\t' * recursion_level, page.lft, page.rght, left, right) | |
# save | |
page.lft = left | |
page.rght = right | |
if commit: | |
page.save() | |
return right + 1 | |
class Command(BaseCommand): | |
args = '<page_id page_id ...> [--dry-run]' | |
help = """ | |
This script attempts to rebuild a malformed django-cms-mptt tree. It checks the | |
parent_id field only. This means it will potentially reorder elements of the | |
same level as it does not check their left and right values. The output might | |
appear somewhat counter-intuitive to you, an element with children will have its | |
body split by children elements. Have a look at the example: | |
(id) parent_element_title | |
(id) child_element_title | |
13-14=>13-14 # child element footer | |
12-15=>12-15 # parent element footer | |
Numbers' format: left_before-right_before=>left_after-right_after. | |
You may either provide a list of ids that you want to rebuild (and children thereof) | |
or parse all top level elements by providing no command line arguments. | |
Adapted for python from http://www.sitepoint.com/hierarchical-data-database-3/ | |
by tu-br, 1338913297 ;) | |
""" | |
option_list = BaseCommand.option_list + ( | |
make_option('--dry-run', | |
action='store_true', | |
dest='dry-run', | |
default=False, | |
help='Don\'t commit, just list the tree with proposed changes. '), | |
) | |
def handle(self, *args, **options): | |
commit = False if options['dry-run'] else True # whether to commit changes | |
commit or self.stdout.write("### This is a dry run only. No changes will be made to the database. ###\n") | |
if len(args) > 0: | |
for page_id in args: | |
try: | |
page = Page.objects.get(pk=int(page_id)) | |
rebuild_tree(page.id, commit=commit) | |
except Page.DoesNotExist: | |
raise CommandError('Page "%s" does not exist' % page_id) | |
else: | |
top_level_cms_pages = Page.objects.all().filter(parent=None) | |
for top_level_cms_page in top_level_cms_pages: | |
rebuild_tree(top_level_cms_page.id, commit=commit) | |
commit or self.stdout.write("### This is a dry run only. No changes will be made to the database. ###\n") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment