def handle(self, **options): any_problems_fixed = False for page in Page.objects.all(): try: page.specific except page.specific_class.DoesNotExist: self.stdout.write( "Page %d (%s) is missing a subclass record; deleting." % (page.id, page.title)) any_problems_fixed = True page.delete() (bad_alpha, bad_path, orphans, bad_depth, bad_numchild) = Page.find_problems() if bad_depth: self.stdout.write("Incorrect depth value found for pages: %s" % self.numberlist_to_string(bad_depth)) if bad_numchild: self.stdout.write("Incorrect numchild value found for pages: %s" % self.numberlist_to_string(bad_numchild)) if bad_depth or bad_numchild: Page.fix_tree(destructive=False) any_problems_fixed = True if orphans: # The 'orphans' list as returned by treebeard only includes pages that are # missing an immediate parent; descendants of orphans are not included. # Deleting only the *actual* orphans is a bit silly (since it'll just create # more orphans), so generate a queryset that contains descendants as well. orphan_paths = Page.objects.filter(id__in=orphans).values_list( 'path', flat=True) filter_conditions = [] for path in orphan_paths: filter_conditions.append(Q(path__startswith=path)) # combine filter_conditions into a single ORed condition final_filter = functools.reduce(operator.or_, filter_conditions) # build a queryset of all pages to be removed; this must be a vanilla Django # queryset rather than a treebeard MP_NodeQuerySet, so that we bypass treebeard's # custom delete() logic that would trip up on the very same corruption that we're # trying to fix here. pages_to_delete = models.query.QuerySet(Page).filter(final_filter) self.stdout.write("Orphaned pages found:") for page in pages_to_delete: self.stdout.write("ID %d: %s" % (page.id, page.title)) self.stdout.write('') if options.get('interactive', True): yes_or_no = input("Delete these pages? [y/N] ") delete_orphans = yes_or_no.lower().startswith('y') self.stdout.write('') else: # Running tests, check for the "delete_orphans" option delete_orphans = options.get('delete_orphans', False) if delete_orphans: deletion_count = len(pages_to_delete) pages_to_delete.delete() self.stdout.write( "%d orphaned page%s deleted." % (deletion_count, "s" if deletion_count != 1 else "")) any_problems_fixed = True if any_problems_fixed: # re-run find_problems to see if any new ones have surfaced (bad_alpha, bad_path, orphans, bad_depth, bad_numchild) = Page.find_problems() if any((bad_alpha, bad_path, orphans, bad_depth, bad_numchild)): self.stdout.write("Remaining problems (cannot fix automatically):") if bad_alpha: self.stdout.write( "Invalid characters found in path for pages: %s" % self.numberlist_to_string(bad_alpha)) if bad_path: self.stdout.write("Invalid path length found for pages: %s" % self.numberlist_to_string(bad_path)) if orphans: self.stdout.write("Orphaned pages found: %s" % self.numberlist_to_string(orphans)) if bad_depth: self.stdout.write("Incorrect depth value found for pages: %s" % self.numberlist_to_string(bad_depth)) if bad_numchild: self.stdout.write( "Incorrect numchild value found for pages: %s" % self.numberlist_to_string(bad_numchild)) elif any_problems_fixed: self.stdout.write("All problems fixed.") else: self.stdout.write("No problems found.")
def handle(self, **options): any_problems_fixed = False for page in Page.objects.all(): try: page.specific except page.specific_class.DoesNotExist: self.stdout.write("Page %d (%s) is missing a subclass record; deleting." % (page.id, page.title)) any_problems_fixed = True page.delete() (bad_alpha, bad_path, orphans, bad_depth, bad_numchild) = Page.find_problems() if bad_depth: self.stdout.write("Incorrect depth value found for pages: %s" % self.numberlist_to_string(bad_depth)) if bad_numchild: self.stdout.write("Incorrect numchild value found for pages: %s" % self.numberlist_to_string(bad_numchild)) if bad_depth or bad_numchild: Page.fix_tree(destructive=False) any_problems_fixed = True if orphans: # The 'orphans' list as returned by treebeard only includes pages that are # missing an immediate parent; descendants of orphans are not included. # Deleting only the *actual* orphans is a bit silly (since it'll just create # more orphans), so generate a queryset that contains descendants as well. orphan_paths = Page.objects.filter(id__in=orphans).values_list('path', flat=True) filter_conditions = [] for path in orphan_paths: filter_conditions.append(Q(path__startswith=path)) # combine filter_conditions into a single ORed condition final_filter = functools.reduce(operator.or_, filter_conditions) # build a queryset of all pages to be removed; this must be a vanilla Django # queryset rather than a treebeard MP_NodeQuerySet, so that we bypass treebeard's # custom delete() logic that would trip up on the very same corruption that we're # trying to fix here. pages_to_delete = models.query.QuerySet(Page).filter(final_filter) self.stdout.write("Orphaned pages found:") for page in pages_to_delete: self.stdout.write("ID %d: %s" % (page.id, page.title)) self.stdout.write('') if options.get('interactive', True): yes_or_no = input("Delete these pages? [y/N] ") delete_orphans = yes_or_no.lower().startswith('y') self.stdout.write('') else: # Running tests, check for the "delete_orphans" option delete_orphans = options.get('delete_orphans', False) if delete_orphans: deletion_count = len(pages_to_delete) pages_to_delete.delete() self.stdout.write( "%d orphaned page%s deleted." % (deletion_count, "s" if deletion_count != 1 else "") ) any_problems_fixed = True if any_problems_fixed: # re-run find_problems to see if any new ones have surfaced (bad_alpha, bad_path, orphans, bad_depth, bad_numchild) = Page.find_problems() if any((bad_alpha, bad_path, orphans, bad_depth, bad_numchild)): self.stdout.write("Remaining problems (cannot fix automatically):") if bad_alpha: self.stdout.write( "Invalid characters found in path for pages: %s" % self.numberlist_to_string(bad_alpha) ) if bad_path: self.stdout.write("Invalid path length found for pages: %s" % self.numberlist_to_string(bad_path)) if orphans: self.stdout.write("Orphaned pages found: %s" % self.numberlist_to_string(orphans)) if bad_depth: self.stdout.write("Incorrect depth value found for pages: %s" % self.numberlist_to_string(bad_depth)) if bad_numchild: self.stdout.write( "Incorrect numchild value found for pages: %s" % self.numberlist_to_string(bad_numchild) ) elif any_problems_fixed: self.stdout.write("All problems fixed.") else: self.stdout.write("No problems found.")
def handle(self, *args, **kwargs): # wagtail creates the root page for us root = Page.objects.get(slug='root') # NOTE: logic for creating pages based on wagtail core migration # 0002 initial data, which creates initial site and welcome page # delete default home wagtail home page Page.objects.filter(slug='home', title__contains='Welcome').delete() # Create PPA homepage home = HomePage.objects.filter(slug='home').first() if not home: home = HomePage.objects.create( title='Princeton Prosody Archive', slug='home', depth=2, numchild=0, show_in_menus=True, path='00010001', content_type=ContentType.objects.get_for_model(HomePage), ) home.show_in_menus = True home.path = '00010001' home.url_path = '/home/' home.save() # create editorial index page editorial = EditorialIndexPage.objects.first() if not editorial: editorial = EditorialIndexPage.objects.create( title='Editorial', slug='editorial', depth=home.depth + 1, show_in_menus=False, path=home.path + '0001', content_type=ContentType.objects.get_for_model(EditorialIndexPage) ) ## create collections page collections = CollectionPage.objects.first() if not collections: collections = CollectionPage.objects.create( title='About the Collections', slug='collections', depth=home.depth + 1, show_in_menus=False, path=home.path + '0002', content_type=ContentType.objects.get_for_model(CollectionPage) ) # create content page stubs if they are not already present index = 3 for slug, title in self.content_pages.items(): cpage = Page.objects.filter(slug=slug).first() if not cpage: # use special contributor page for contributors if slug == 'contributors': page_type = ContributorPage else: page_type = ContentPage ContentPage.objects.create( title=title, slug=slug, depth=home.depth + 1, path='{}{:04d}'.format(home.path, index), show_in_menus=True, content_type=ContentType.objects.get_for_model(page_type) ) index += 1 # create wagtail site from django site and associate new homepage # self.create_wagtail_site(home) self.create_wagtail_site(home.page_ptr) # associate default page previews for home page if not set if not any([home.page_preview_1, home.page_preview_2]): home.page_preview_1 = ContentPage.objects.get(slug='prosody') home.page_preview_2 = ContentPage.objects.get(slug='history') home.save() # let treebeard fix the hierarchy Page.fix_tree()