def process_redirects(): # We create the Redirects here. We don't try and port over the # version information for the formerly-page-text-based redirects. global redirects from pages.models import Page, slugify from redirects.models import Redirect u = get_robot_user() for from_pagename, to_pagename in redirects: try: to_page = Page.objects.get(slug=slugify(to_pagename)) except Page.DoesNotExist: print "Error creating redirect: %s --> %s" % ( from_pagename, to_pagename) print " (page %s does not exist)" % to_pagename continue if slugify(from_pagename) == to_page.slug: continue if not Redirect.objects.filter(source=slugify(from_pagename)): r = Redirect(source=slugify(from_pagename), destination=to_page) r.save(user=u, comment="Automated edit. Creating redirect.") print "Redirect %s --> %s created" % (from_pagename, to_pagename)
def import_redirect(from_pagename): # We create the Redirects here. We don't try and port over the # version information for the formerly-page-text-based redirects. to_pagename = parse_redirect(from_pagename) if to_pagename is None: print "Error creating redirect: %s has no link" % from_pagename return to_pagename = fix_pagename(to_pagename) from pages.models import Page, slugify from redirects.models import Redirect u = get_robot_user() try: to_page = Page.objects.get(slug=slugify(to_pagename)) except Page.DoesNotExist: print "Error creating redirect: %s --> %s" % ( from_pagename.encode('utf-8'), to_pagename.encode('utf-8')) print " (page %s does not exist)" % to_pagename.encode('utf-8') return if slugify(from_pagename) == to_page.slug: return if not Redirect.objects.filter(source=slugify(from_pagename)): r = Redirect(source=slugify(from_pagename), destination=to_page) try: r.save(user=u, comment="Automated edit. Creating redirect.") except IntegrityError: connection.close() print "Redirect %s --> %s created" % (from_pagename.encode('utf-8'), to_pagename.encode('utf-8'))
def process_redirects(): # We create the Redirects here. We don't try and port over the # version information for the formerly-page-text-based redirects. global redirects from pages.models import Page, slugify from redirects.models import Redirect u = get_robot_user() for from_pagename, to_pagename in redirects: try: to_page = Page.objects.get(slug=slugify(to_pagename)) except Page.DoesNotExist: print "Error creating redirect: %s --> %s" % (from_pagename, to_pagename) print " (page %s does not exist)" % to_pagename continue if slugify(from_pagename) == to_page.slug: continue if not Redirect.objects.filter(source=slugify(from_pagename)): r = Redirect(source=slugify(from_pagename), destination=to_page) r.save(user=u, comment="Automated edit. Creating redirect.") print "Redirect %s --> %s created" % (from_pagename, to_pagename)
def test_move_redirects(self): p = Page(region=self.sf) p.content = "<p>A page.</p>" p.name = "Page content" p.save() redir = Redirect( source="short name", destination=p, region=self.sf) redir.save() move_to_region(self.oak, pages=[p], redirects=[redir]) # Redirect should be in Oak self.assertEqual(Redirect.objects.filter(region=self.oak).count(), 1)
def test_move_with_fks(self): ########################################################### # Moving should carry along files and FK'ed items that # point to it. ########################################################### p = Page(region=self.sf) p.content = "<p>A page with files and a map in SF.</p>" p.name = "Page With FKs" p.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug, region=self.sf) pf.save() # Create a redirect that points at the page. redirect = Redirect(source="foobar", destination=p, region=self.sf) redirect.save() # Create a map that points at the page. points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""") map = MapData(points=points, page=p, region=self.sf) map.save() # Add tags to page tagset = PageTagSet(page=p, region=self.sf) tagset.save() tag = Tag(name="tag1", region=self.sf) tag.save() tagset.tags.add(tag) move_to_region(self.oak, pages=[p]) # Check to see that the related objects were moved. p = Page.objects.get(name="Page With FKs", region=self.oak) self.assertEqual(len(MapData.objects.filter(page=p, region=self.oak)), 1) self.assertEqual(len(p.pagetagset.tags.all()), 1) self.assertEqual(len(Redirect.objects.filter(destination=p, region=self.oak)), 1) self.assertEqual(len(PageFile.objects.filter(slug=p.slug, region=self.oak)), 1) # Check to see that version history was moved as well self.assertEquals(p.versions.all().count(), 1) self.assertEqual(len(MapData.versions.filter(page=p, region=self.oak)), 1) for pts in p.pagetagset.tags.all(): self.assertEqual(pts.versions.all().count(), 1) self.assertEqual(len(Redirect.versions.filter(destination=p, region=self.oak)), 1) self.assertEqual(len(PageFile.versions.filter(slug=p.slug, region=self.oak)), 1) # ..and that the page is no longer in the SF region self.assertFalse(Page.objects.filter(region=self.sf, name="Page With FKs").exists())
def test_move_redirect_destination(self): # Destination page should be transparently moved if not specified p = Page(region=self.sf) p.content = "<p>A page.</p>" p.name = "Page content not moved directly" p.save() redir = Redirect( source="short name", destination=p, region=self.sf) redir.save() move_to_region(self.oak, redirects=[redir]) # Redirect should be in Oak self.assertEqual(Redirect.objects.filter(region=self.oak).count(), 1) # ..and page self.assertTrue(Page.objects.filter(slug='page content not moved directly', region=self.oak).exists())
def rename_to(self, pagename): """ Renames the page to `pagename`. Moves related objects around accordingly. """ def _get_slug_lookup(unique_together, obj, new_p): d = {} for field in unique_together: d[field] = getattr(obj, field) d['slug'] = new_p.slug return d from redirects.models import Redirect from redirects.exceptions import RedirectToSelf if Page.objects.filter(slug=slugify(pagename)): if slugify(pagename) == self.slug: # The slug is the same but we're changing the name. old_name = self.name self.name = pagename self.save(comment='Renamed from "%s"' % old_name) return else: raise exceptions.PageExistsError( "The page '%s' already exists!" % pagename) # Copy the current page into the new page, zeroing out the # primary key and setting a new name and slug. new_p = copy(self) new_p.pk = None new_p.name = pagename new_p.slug = slugify(pagename) new_p.save(comment='Renamed from "%s"' % self.name) # Get all related objects before the original page is deleted. related_objs = [] for r in self._meta.get_all_related_objects(): try: rel_obj = getattr(self, r.get_accessor_name()) except: continue # No object for this relation. # Is this a related /set/, e.g. redirect_set? if isinstance(rel_obj, models.Manager): # list() freezes the QuerySet, which we don't want to be # fetched /after/ we delete the page. related_objs.append( (r.get_accessor_name(), list(rel_obj.all()))) else: related_objs.append((r.get_accessor_name(), rel_obj)) # Create a redirect from the starting pagename to the new pagename. redirect = Redirect(source=self.slug, destination=new_p) # Creating the redirect causes the starting page to be deleted. redirect.save() # Point each related object to the new page and save the object with a # 'was renamed' comment. for attname, rel_obj in related_objs: if isinstance(rel_obj, list): for obj in rel_obj: obj.pk = None # Reset the primary key before saving. try: getattr(new_p, attname).add(obj) obj.save(comment="Parent page renamed") except RedirectToSelf, s: # We don't want to create a redirect to ourself. # This happens during a rename -> rename-back # cycle. continue else: # This is an easy way to set obj to point to new_p. setattr(new_p, attname, rel_obj) rel_obj.pk = None # Reset the primary key before saving. rel_obj.save(comment="Parent page renamed")
def test_page_rename(self): p = Page() p.content = "<p>The page content.</p>" p.name = "Original page" p.save() p.rename_to("New page") # Renamed-to page should exist. new_p = Page.objects.get(name="New page") # new_p should have the same content. self.assertEqual(new_p.content, p.content) # "Original page" should no longer exist. pgs = Page.objects.filter(name="Original page") self.assertEqual(len(pgs), 0) # and a redirect from "original page" to "New page" should exist. Redirect.objects.filter(source="original page", destination=new_p) ########################################################### # Renaming to a page that already exists should raise an # exception and not affect the original page. ########################################################### p = Page() p.content = "<p>Hello, world.</p>" p.name = "Page A" p.save() self.assertRaises(exceptions.PageExistsError, p.rename_to, "New page") # p should be unaffected. No redirect should be created. p = Page.objects.get(name="Page A") self.assertEqual(p.content, "<p>Hello, world.</p>") self.assertEqual(len(Redirect.objects.filter(source="page a")), 0) ########################################################### # Renaming should carry along files and FK'ed items that # point to it. ########################################################### p = Page() p.content = "<p>A page with files and a map.</p>" p.name = "Page With FKs" p.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug) pf.save() # Create a redirect that points at the page. redirect = Redirect(source="foobar", destination=p) redirect.save() # Create a map that points at the page. points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""") map = MapData(points=points, page=p) map.save() p.rename_to("New Page With FKs") new_p = Page.objects.get(name="New Page With FKs") self.assertEqual(len(MapData.objects.filter(page=new_p)), 1) # Two redirects: one we created explicitly and one that was # created during rename_to() self.assertEqual(len(Redirect.objects.filter(destination=new_p)), 2) self.assertEqual(len(PageFile.objects.filter(slug=new_p.slug)), 1) # Renaming should keep slugs pointed at old page /and/ copy # them to the new page. self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1) ########################################################### # Renaming with multiple files. ########################################################### p = Page() p.content = "<p>A new page with multiple files.</p>" p.name = "Page with multiple files" p.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug) pf.save() pf = PageFile(file=ContentFile("foo2"), name="file2.txt", slug=p.slug) pf.save() pf = PageFile(file=ContentFile("foo3"), name="file3.txt", slug=p.slug) pf.save() p.rename_to("A page with multiple files 2") p = Page.objects.get(name="A page with multiple files 2") self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 3) ########################################################### # Reverting a renamed page should be possible and should # restore files and FK'ed items that were pointed at the # original page. The renamed-to page should still exist # after the revert and should still have its own files and # FK'ed items pointed at it. ########################################################### p = Page(name="Page With FKs", slug="page with fks") # get the version right before it was deleted v_before_deleted = len(p.versions.all()) - 1 p_h = p.versions.as_of(version=v_before_deleted) p_h.revert_to() p = Page.objects.get(name="Page With FKs") self.assertEqual(len(MapData.objects.filter(page=p)), 1) self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1) p2 = Page.objects.get(name="New Page With FKs") self.assertEqual(len(MapData.objects.filter(page=p2)), 1) self.assertEqual(len(PageFile.objects.filter(slug=p2.slug)), 1) self.assertEqual(len(Redirect.objects.filter(destination=p2)), 1) ########################################################### # Renaming a page and then renaming it back. ########################################################### # 1. Simple case p = Page(name="Page X", content="<p>Foobar</p>") p.save() p.rename_to("Page Y") self.assertEqual(len(Page.objects.filter(name="Page X")), 0) self.assertEqual(len(Page.objects.filter(name="Page Y")), 1) p_new = Page.objects.get(name="Page Y") p_new.rename_to("Page X") self.assertEqual(len(Page.objects.filter(name="Page X")), 1) self.assertEqual(len(Page.objects.filter(name="Page Y")), 0) # 2. If we have FKs pointed at the page this shouldn't be # totally f****d. p = Page(name="Page X2", content="<p>Foo X</p>") p.save() points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""") map = MapData(points=points, page=p) map.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foooo"), name="file_foo.txt", slug=p.slug) pf.save() p.rename_to("Page Y2") p_new = Page.objects.get(name="Page Y2") # FK points at the page we renamed to. self.assertEqual(len(MapData.objects.filter(page=p_new)), 1) self.assertEqual(len(PageFile.objects.filter(slug=p_new.slug)), 1) # Now rename it back. p_new.rename_to("Page X2") p = Page.objects.get(name="Page X2") # After rename-back-to, FK points to the renamed-back-to page. self.assertEqual(len(MapData.objects.filter(page=p)), 1) self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1) ########################################################### # Renaming a page but keeping the same slug ########################################################### p = Page(name="Foo A", content="<p>Foo A</p>") p.save() p.rename_to("FOO A") # Name has changed. self.assertEqual(len(Page.objects.filter(name="FOO A")), 1) # Has the same history, with a new entry for the name change. p = Page.objects.get(name="FOO A") p1, p0 = p.versions.all() self.assertEqual(p1.name, 'FOO A') self.assertEqual(p0.name, 'Foo A') self.assertEqual(p0.content, p1.content) ########################################################### # Renaming a page twice (A -> B -> C) and then revert A to # an existing state. ########################################################### p = Page(name="Bar A", content="<p>Bar A</p>") p.save() p.rename_to("Bar B") p = Page.objects.get(name="Bar B") p.rename_to("Bar C") p = Page(name="Bar A", slug="bar a") p_h = p.versions.as_of(version=1) p_h.revert_to() ########################################################### # Renaming a page back and forth and reverting. ########################################################### p = Page(name="Zoo A", content="<p>Zoo A</p>") p.save() p.rename_to("Zoo B") p = Page.objects.get(name="Zoo B") p.rename_to("Zoo A") p = Page.objects.get(name="Zoo A") p.rename_to("Zoo B") p = Page(name="Zoo A", slug="zoo a") p_h = p.versions.as_of(version=1) p_h.revert_to() ########################################################### # page A, rename to B, then create new A, rename B to C, # rename C to B, then revert C to first version ########################################################### p = Page(name="Mike A", content="<p>A</p>") p.save() p.rename_to("Mike B") new_a = Page(name="Mike A", content="<p>A new</p>") new_a.save() p = Page.objects.get(name="Mike B") p.rename_to("Mike C") p = Page.objects.get(name="Mike C") p.rename_to("Mike B") p_c = Page(name="Mike C", slug="mike c") p_h = p_c.versions.as_of(version=1) p_h.revert_to()
def get_posts(item, uri_parser, user): """ If the given Article has already been created, skip it. If not, create Article object and Redirect object. """ alreadyThere = False link = unicode(item.find('link').contents[0]) slug = uri_parser.parse(link).path.strip('/') for article in Article.objects.all(): if article.slug == slug[:100]: alreadyThere = True break if not alreadyThere: title = unicode(item.find('title').contents[0]) post_id = item.find('wp:post_id').string post_id = int(post_id) body = unicode(item.find('content:encoded').contents[0]) body = replace_short_code(body) try: # There may not be a file associated with a post. # If so, catch that error. fgroup = AssociatedFile.objects.filter(post_id=post_id) for f in fgroup: body = correct_media_file_path(body, f.file) except: pass post_date = unicode(item.find('wp:post_date').contents[0]) post_dt = datetime.strptime(post_date, '%Y-%m-%d %H:%M:%S') tags_raw = item.findAll('category', domain="post_tag") tags_list = [] if tags_raw: for tag in tags_raw: if len(','.join(tags_list)) + len(tag.string) <= 255: tags_list.append(tag.string[:50]) article = { 'headline': title, 'guid': str(uuid.uuid1()), 'slug': slug[:100], 'body': body, 'tags': ','.join(tags_list), 'timezone': 'US/Central', 'syndicate': True, 'featured': False, 'release_dt': post_dt, 'creator': user, 'creator_username': user.username, 'allow_anonymous_view': True, 'allow_user_view': False, 'allow_member_view': False, 'allow_anonymous_edit': False, 'allow_user_edit': False, 'allow_member_edit': False, 'owner': user, 'owner_username': user.username, 'status': True, 'status_detail': 'active' } redirect = { 'from_url': slug[:100], 'to_url': os.path.join('articles', slug[:100]) } a = Article(**article) a.save() r = Redirect(**redirect) r.save()
def rename_to(self, pagename): """ Renames the page to `pagename`. Moves related objects around accordingly. """ def _get_slug_lookup(unique_together, obj, new_p): d = {} for field in unique_together: d[field] = getattr(obj, field) d['slug'] = new_p.slug return d def _already_exists(obj): M = obj.__class__ unique_vals = unique_lookup_values_for(obj) if not unique_vals: return False return M.objects.filter(**unique_vals).exists() from redirects.models import Redirect from redirects.exceptions import RedirectToSelf if Page(slug=slugify(pagename), region=self.region).exists(): if slugify(pagename) == self.slug: # The slug is the same but we're changing the name. old_name = self.name self.name = pagename self.save(comment=_('Renamed from "%s"') % old_name) return else: raise exceptions.PageExistsError( _("The page '%s' already exists!") % pagename) # Copy the current page into the new page, zeroing out the # primary key and setting a new name and slug. new_p = copy(self) new_p.pk = None new_p.name = pagename new_p.slug = slugify(pagename) new_p._in_rename = True new_p.save(comment=_('Renamed from "%s"') % self.name) # Get all related objects before the original page is deleted. related_objs = self._get_related_objs() # Cache all ManyToMany values on related objects so we can restore them # later--otherwise they will be lost when page is deleted. for attname, rel_obj_list in related_objs: if not isinstance(rel_obj_list, list): rel_obj_list = [rel_obj_list] for rel_obj in rel_obj_list: rel_obj._m2m_values = dict( (f.attname, list(getattr(rel_obj, f.attname).all())) for f in rel_obj._meta.many_to_many) # Create a redirect from the starting pagename to the new pagename. redirect = Redirect(source=self.slug, destination=new_p, region=self.region) # Creating the redirect causes the starting page to be deleted. redirect.save() # Point each related object to the new page and save the object with a # 'was renamed' comment. for attname, rel_obj in related_objs: if isinstance(rel_obj, list): for obj in rel_obj: obj.pk = None # Reset the primary key before saving. try: getattr(new_p, attname).add(obj) if _already_exists(obj): continue if is_versioned(obj): obj.save(comment=_("Parent page renamed")) else: obj.save() # Restore any m2m fields now that we have a new pk for name, value in obj._m2m_values.items(): setattr(obj, name, value) except RedirectToSelf, s: # We don't want to create a redirect to ourself. # This happens during a rename -> rename-back # cycle. continue else: # This is an easy way to set obj to point to new_p. setattr(new_p, attname, rel_obj) rel_obj.pk = None # Reset the primary key before saving. if _already_exists(rel_obj): continue if is_versioned(rel_obj): rel_obj.save(comment=_("Parent page renamed")) else: rel_obj.save() # Restore any m2m fields now that we have a new pk for name, value in rel_obj._m2m_values.items(): setattr(rel_obj, name, value)
def test_page_rename(self): p = Page() p.content = "<p>The page content.</p>" p.name = "Original page" p.save() p.rename_to("New page") # Renamed-to page should exist. new_p = Page.objects.get(name="New page") # new_p should have the same content. self.assertEqual(new_p.content, p.content) # "Original page" should no longer exist. pgs = Page.objects.filter(name="Original page") self.assertEqual(len(pgs), 0) # and a redirect from "original page" to "New page" should exist. Redirect.objects.filter(source="original page", destination=new_p) ########################################################### # Renaming to a page that already exists should raise an # exception and not affect the original page. ########################################################### p = Page() p.content = "<p>Hello, world.</p>" p.name = "Page A" p.save() self.assertRaises(exceptions.PageExistsError, p.rename_to, "New page") # p should be unaffected. No redirect should be created. p = Page.objects.get(name="Page A") self.assertEqual(p.content, "<p>Hello, world.</p>") self.assertEqual(len(Redirect.objects.filter(source="page a")), 0) ########################################################### # Renaming should carry along files and FK'ed items that # point to it. ########################################################### p = Page() p.content = "<p>A page with files and tags</p>" p.name = "Page With FKs" p.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug) pf.save() # Create a redirect that points at the page. redirect = Redirect(source="foobar", destination=p) redirect.save() # Add tags to page tagset = PageTagSet(page=p) tagset.save() tag = Tag(name="tag1") tag.save() tagset.tags.add(tag) p.rename_to("New Page With FKs") new_p = Page.objects.get(name="New Page With FKs") self.assertEqual(len(new_p.pagetagset.tags.all()), 1) # Two redirects: one we created explicitly and one that was # created during rename_to() self.assertEqual(len(Redirect.objects.filter(destination=new_p)), 2) self.assertEqual(len(PageFile.objects.filter(slug=new_p.slug)), 1) # Renaming should keep slugs pointed at old page /and/ copy # them to the new page. self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1) ########################################################### # Renaming with multiple files. ########################################################### p = Page() p.content = "<p>A new page with multiple files.</p>" p.name = "Page with multiple files" p.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug) pf.save() pf = PageFile(file=ContentFile("foo2"), name="file2.txt", slug=p.slug) pf.save() pf = PageFile(file=ContentFile("foo3"), name="file3.txt", slug=p.slug) pf.save() p.rename_to("A page with multiple files 2") p = Page.objects.get(name="A page with multiple files 2") self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 3) ########################################################### # Reverting a renamed page should be possible and should # restore files and FK'ed items that were pointed at the # original page. The renamed-to page should still exist # after the revert and should still have its own files and # FK'ed items pointed at it. ########################################################### p = Page(name="Page With FKs", slug="page with fks") # get the version right before it was deleted v_before_deleted = len(p.versions.all()) - 1 p_h = p.versions.as_of(version=v_before_deleted) p_h.revert_to() p = Page.objects.get(name="Page With FKs") self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1) p2 = Page.objects.get(name="New Page With FKs") self.assertEqual(len(PageFile.objects.filter(slug=p2.slug)), 1) self.assertEqual(len(Redirect.objects.filter(destination=p2)), 1) ########################################################### # Renaming a page and then renaming it back. ########################################################### # 1. Simple case p = Page(name="Page X", content="<p>Foobar</p>") p.save() p.rename_to("Page Y") self.assertEqual(len(Page.objects.filter(name="Page X")), 0) self.assertEqual(len(Page.objects.filter(name="Page Y")), 1) p_new = Page.objects.get(name="Page Y") p_new.rename_to("Page X") self.assertEqual(len(Page.objects.filter(name="Page X")), 1) self.assertEqual(len(Page.objects.filter(name="Page Y")), 0) # 2. If we have FKs pointed at the page this shouldn't be # totally f****d. p = Page(name="Page X2", content="<p>Foo X</p>") p.save() # Create a file that points at the page. pf = PageFile(file=ContentFile("foooo"), name="file_foo.txt", slug=p.slug) pf.save() p.rename_to("Page Y2") p_new = Page.objects.get(name="Page Y2") # FK points at the page we renamed to. self.assertEqual(len(PageFile.objects.filter(slug=p_new.slug)), 1) # Now rename it back. p_new.rename_to("Page X2") p = Page.objects.get(name="Page X2") # After rename-back-to, FK points to the renamed-back-to page. self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1) ########################################################### # Renaming a page but keeping the same slug ########################################################### p = Page(name="Foo A", content="<p>Foo A</p>") p.save() p.rename_to("FOO A") # Name has changed. self.assertEqual(len(Page.objects.filter(name="FOO A")), 1) # Has the same history, with a new entry for the name change. p = Page.objects.get(name="FOO A") p1, p0 = p.versions.all() self.assertEqual(p1.name, 'FOO A') self.assertEqual(p0.name, 'Foo A') self.assertEqual(p0.content, p1.content) ########################################################### # Renaming a page twice (A -> B -> C) and then revert A to # an existing state. ########################################################### p = Page(name="Bar A", content="<p>Bar A</p>") p.save() p.rename_to("Bar B") p = Page.objects.get(name="Bar B") p.rename_to("Bar C") p = Page(name="Bar A", slug="bar a") p_h = p.versions.as_of(version=1) p_h.revert_to() ########################################################### # Renaming a page back and forth and reverting. ########################################################### p = Page(name="Zoo A", content="<p>Zoo A</p>") p.save() p.rename_to("Zoo B") p = Page.objects.get(name="Zoo B") p.rename_to("Zoo A") p = Page.objects.get(name="Zoo A") p.rename_to("Zoo B") p = Page(name="Zoo A", slug="zoo a") p_h = p.versions.as_of(version=1) p_h.revert_to() ########################################################### # page A, rename to B, then create new A, rename B to C, # rename C to B, then revert C to first version ########################################################### p = Page(name="Mike A", content="<p>A</p>") p.save() p.rename_to("Mike B") new_a = Page(name="Mike A", content="<p>A new</p>") new_a.save() p = Page.objects.get(name="Mike B") p.rename_to("Mike C") p = Page.objects.get(name="Mike C") p.rename_to("Mike B") p_c = Page(name="Mike C", slug="mike c") p_h = p_c.versions.as_of(version=1) p_h.revert_to()