general: display correct page when same slug is repeated in hierarchy (#38152)

This commit is contained in:
Frédéric Péters 2020-01-12 14:20:21 +01:00
parent 8363b36208
commit f5ed29d569
2 changed files with 59 additions and 4 deletions

View File

@ -436,18 +436,31 @@ def page(request):
request.session['visited'] = True
return HttpResponseRedirect(settings.COMBO_WELCOME_PAGE_PATH)
pages = {x.slug: x for x in Page.objects.filter(slug__in=parts)}
pages = {}
for page in Page.objects.filter(slug__in=parts):
if not page.slug in pages:
pages[page.slug] = []
pages[page.slug].append(page)
if pages == {} and parts == ['index'] and Page.objects.count() == 0:
return empty_site(request)
i = 0
hierarchy_ids = [None]
while i < len(parts):
try:
page = pages[parts[i]]
except KeyError:
slug_pages = pages.get(parts[i])
if slug_pages is None or len(slug_pages) == 0:
page = None
break
elif len(slug_pages) == 1:
page = slug_pages[0]
else:
# multiple pages with same slugs
try:
page = [x for x in slug_pages if x.parent_id == hierarchy_ids[-1]][0]
except IndexError:
page = None
break
if page.parent_id != hierarchy_ids[-1]:
if i == 0:
# root page should be at root but maybe the page is a child of

View File

@ -404,6 +404,48 @@ def test_subpage_location(app):
assert 'Grand child of second' in resp.text
def test_repeated_slug(app):
Page.objects.all().delete()
page1 = Page(title='Home Page', slug='index', template_name='standard')
page1.save()
page2 = Page(title='Second top level page', slug='second', template_name='standard')
page2.save()
page3 = Page(title='Child of second', slug='child-second',
template_name='standard', parent=page2)
page3.save()
page4 = Page(title='Grand child of second (named third)', slug='third',
template_name='standard', parent=page3)
page4.save()
page5 = Page(title='Third top level page', slug='third', template_name='standard')
page5.save()
for i, page in enumerate((page1, page2, page3, page4, page5)):
page.order = i
page.save()
resp = app.get('/third/', status=200)
assert 'Third top level page' in resp.text
resp = app.get('/second/child-second/third/', status=200)
assert 'Grand child of second (named third)' in resp.text
# reverse page order, and expect same behaviour
for i, page in enumerate(reversed((page1, page2, page3, page4, page5))):
page.order = i
page.save()
resp = app.get('/third/', status=200)
assert 'Third top level page' in resp.text
resp = app.get('/second/child-second/third/', status=200)
assert 'Grand child of second (named third)' in resp.text
def test_menu(app):
Page.objects.all().delete()
Page.objects.create(title='Page1', slug='index', template_name='standard', exclude_from_navigation=False)