general: create page hierarchy beforehand (#24238)
This commit is contained in:
parent
9e6adee4f9
commit
35d9a1bbba
|
@ -95,8 +95,8 @@ def get_page_dict(request, page, manifest):
|
||||||
if page_dict.get('external') and icon_cells[0].embed_page:
|
if page_dict.get('external') and icon_cells[0].embed_page:
|
||||||
page_dict['external'] = False
|
page_dict['external'] = False
|
||||||
|
|
||||||
if hasattr(page, '_children') and page._children:
|
if page.slug == 'index' and page.parent_id is None: # home
|
||||||
children = page._children
|
children = page.get_siblings()[1:]
|
||||||
else:
|
else:
|
||||||
children = page.get_children()
|
children = page.get_children()
|
||||||
|
|
||||||
|
@ -143,18 +143,11 @@ def generate_manifest(request):
|
||||||
# - the application pages are created from the homepage siblings and their
|
# - the application pages are created from the homepage siblings and their
|
||||||
# children
|
# children
|
||||||
# - the application menu is created from direct children of the homepage
|
# - the application menu is created from direct children of the homepage
|
||||||
children = []
|
try:
|
||||||
homepage = None
|
homepage = Page.objects.get(slug='index', parent_id=None)
|
||||||
for page in level0_pages:
|
except Page.DoesNotExist:
|
||||||
if page.slug == 'index':
|
|
||||||
homepage = page
|
|
||||||
else:
|
|
||||||
children.append(page)
|
|
||||||
|
|
||||||
if not homepage:
|
|
||||||
raise GenerationError(_('The homepage needs to be created first.'))
|
raise GenerationError(_('The homepage needs to be created first.'))
|
||||||
|
|
||||||
homepage._children = children
|
|
||||||
manifest.update(get_page_dict(request, homepage, manifest))
|
manifest.update(get_page_dict(request, homepage, manifest))
|
||||||
|
|
||||||
# footer
|
# footer
|
||||||
|
|
|
@ -145,7 +145,6 @@ class Page(models.Model):
|
||||||
related_cells = JSONField(blank=True)
|
related_cells = JSONField(blank=True)
|
||||||
|
|
||||||
_level = None
|
_level = None
|
||||||
_children = None
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['order']
|
ordering = ['order']
|
||||||
|
@ -185,7 +184,7 @@ class Page(models.Model):
|
||||||
pages = [self]
|
pages = [self]
|
||||||
page = self
|
page = self
|
||||||
while page.parent_id:
|
while page.parent_id:
|
||||||
page = page.parent
|
page = page._parent if hasattr(page, '_parent') else page.parent
|
||||||
pages.append(page)
|
pages.append(page)
|
||||||
return list(reversed(pages))
|
return list(reversed(pages))
|
||||||
|
|
||||||
|
@ -202,7 +201,7 @@ class Page(models.Model):
|
||||||
parts = [self]
|
parts = [self]
|
||||||
page = self
|
page = self
|
||||||
while page.parent_id:
|
while page.parent_id:
|
||||||
page = page.parent
|
page = page._parent if hasattr(page, '_parent') else page.parent
|
||||||
parts.append(page)
|
parts.append(page)
|
||||||
parts.reverse()
|
parts.reverse()
|
||||||
try:
|
try:
|
||||||
|
@ -211,12 +210,19 @@ class Page(models.Model):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_siblings(self):
|
def get_siblings(self):
|
||||||
return Page.objects.filter(parent=self.parent)
|
if hasattr(self, '_parent'):
|
||||||
|
if self._parent:
|
||||||
|
return self._parent._children
|
||||||
|
return Page.objects.filter(parent_id=self.parent_id)
|
||||||
|
|
||||||
def get_children(self):
|
def get_children(self):
|
||||||
|
if hasattr(self, '_children'):
|
||||||
|
return self._children
|
||||||
return Page.objects.filter(parent_id=self.id)
|
return Page.objects.filter(parent_id=self.id)
|
||||||
|
|
||||||
def has_children(self):
|
def has_children(self):
|
||||||
|
if hasattr(self, '_children'):
|
||||||
|
return bool(self._children)
|
||||||
return Page.objects.filter(parent_id=self.id).exists()
|
return Page.objects.filter(parent_id=self.id).exists()
|
||||||
|
|
||||||
def get_template_display_name(self):
|
def get_template_display_name(self):
|
||||||
|
@ -282,7 +288,6 @@ class Page(models.Model):
|
||||||
parenting[page.parent_id].append(page)
|
parenting[page.parent_id].append(page)
|
||||||
def fill_list(object_sublist, level=0, parent=None):
|
def fill_list(object_sublist, level=0, parent=None):
|
||||||
for page in object_sublist:
|
for page in object_sublist:
|
||||||
page._children = parenting.get(page.id)
|
|
||||||
if page.parent == parent:
|
if page.parent == parent:
|
||||||
page.level = level
|
page.level = level
|
||||||
reordered.append(page)
|
reordered.append(page)
|
||||||
|
@ -291,6 +296,23 @@ class Page(models.Model):
|
||||||
fill_list(object_list)
|
fill_list(object_list)
|
||||||
return reordered
|
return reordered
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@utils.cache_during_request
|
||||||
|
def get_with_hierarchy_attributes():
|
||||||
|
pages = Page.objects.all()
|
||||||
|
pages_by_id = {}
|
||||||
|
for page in pages:
|
||||||
|
pages_by_id[page.id] = page
|
||||||
|
page._parent = None
|
||||||
|
page._children = []
|
||||||
|
for page in pages:
|
||||||
|
page._parent = pages_by_id[page.parent_id] if page.parent_id else None
|
||||||
|
if page._parent:
|
||||||
|
page._parent._children.append(page)
|
||||||
|
for page in pages:
|
||||||
|
page._children.sort(key=lambda x: x.order)
|
||||||
|
return pages_by_id
|
||||||
|
|
||||||
def visibility(self):
|
def visibility(self):
|
||||||
if self.public:
|
if self.public:
|
||||||
return _('Public')
|
return _('Public')
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
|
|
||||||
|
from combo.data.models import Page
|
||||||
|
|
||||||
|
|
||||||
def render_menu(context, level=0, root_page=None, depth=1):
|
def render_menu(context, level=0, root_page=None, depth=1):
|
||||||
context['root_page'] = root_page
|
context['root_page'] = root_page
|
||||||
if root_page:
|
if root_page:
|
||||||
|
@ -25,17 +28,23 @@ def render_menu(context, level=0, root_page=None, depth=1):
|
||||||
return template.render(context)
|
return template.render(context)
|
||||||
|
|
||||||
def get_menu_context(context, level=0, current_page=None, depth=1):
|
def get_menu_context(context, level=0, current_page=None, depth=1):
|
||||||
|
if 'hierarchical_pages_by_id' not in context:
|
||||||
|
context['hierarchical_pages_by_id'] = Page.get_with_hierarchy_attributes()
|
||||||
|
pages_by_id = context['hierarchical_pages_by_id']
|
||||||
context['depth'] = depth
|
context['depth'] = depth
|
||||||
if current_page is None:
|
if current_page is None:
|
||||||
current_page = context['page']
|
current_page = pages_by_id.get(context['page'].id, context['page'])
|
||||||
|
else:
|
||||||
|
current_page = pages_by_id.get(current_page.id, current_page)
|
||||||
|
|
||||||
if 'root_page' in context:
|
if 'root_page' in context:
|
||||||
|
root_page = pages_by_id[context['root_page'].id] if context.get('root_page') else None
|
||||||
# if the menu is anchored at a specific root page, we make sure the
|
# if the menu is anchored at a specific root page, we make sure the
|
||||||
# current page is in the right path, otherwise we fall back to using
|
# current page is in the right path, otherwise we fall back to using
|
||||||
# the root page as base.
|
# the root page as base.
|
||||||
ariane = current_page.get_parents_and_self()
|
ariane = current_page.get_parents_and_self()
|
||||||
if not context.get('root_page') in ariane:
|
if not root_page in ariane:
|
||||||
page_of_level = context['root_page']
|
page_of_level = root_page
|
||||||
else:
|
else:
|
||||||
page_of_level = current_page.get_page_of_level(level)
|
page_of_level = current_page.get_page_of_level(level)
|
||||||
else:
|
else:
|
||||||
|
@ -51,7 +60,7 @@ def get_menu_context(context, level=0, current_page=None, depth=1):
|
||||||
context['menuitems'] = []
|
context['menuitems'] = []
|
||||||
return context
|
return context
|
||||||
else:
|
else:
|
||||||
if page_of_level is context.get('root_page'):
|
if page_of_level == context.get('root_page'):
|
||||||
elements = page_of_level.get_children()
|
elements = page_of_level.get_children()
|
||||||
else:
|
else:
|
||||||
elements = page_of_level.get_siblings()
|
elements = page_of_level.get_siblings()
|
||||||
|
|
|
@ -103,20 +103,21 @@ def test_page_footer_acquisition(app):
|
||||||
page5.save()
|
page5.save()
|
||||||
ParentContentCell(page=page5, placeholder='footer', order=0).save()
|
ParentContentCell(page=page5, placeholder='footer', order=0).save()
|
||||||
|
|
||||||
# check growth in SQL queries is limited to an additional page lookup
|
# check growth in SQL queries is limited
|
||||||
with CaptureQueriesContext(connection) as ctx:
|
with CaptureQueriesContext(connection) as ctx:
|
||||||
resp = app.get('/second/third/', status=200)
|
resp = app.get('/second/third/', status=200)
|
||||||
assert resp.body.count('BARFOO') == 1
|
assert resp.body.count('BARFOO') == 1
|
||||||
assert resp.body.count('BAR2FOO') == 1
|
assert resp.body.count('BAR2FOO') == 1
|
||||||
queries_count_third = len(ctx.captured_queries)
|
queries_count_third = len(ctx.captured_queries)
|
||||||
assert queries_count_third == queries_count_second + 1
|
assert queries_count_third == queries_count_second
|
||||||
|
|
||||||
with CaptureQueriesContext(connection) as ctx:
|
with CaptureQueriesContext(connection) as ctx:
|
||||||
resp = app.get('/second/third/fourth/', status=200)
|
resp = app.get('/second/third/fourth/', status=200)
|
||||||
assert resp.body.count('BARFOO') == 1
|
assert resp.body.count('BARFOO') == 1
|
||||||
assert resp.body.count('BAR2FOO') == 1
|
assert resp.body.count('BAR2FOO') == 1
|
||||||
queries_count_fourth = len(ctx.captured_queries)
|
queries_count_fourth = len(ctx.captured_queries)
|
||||||
assert queries_count_fourth == queries_count_second + 2
|
# +1 for get_parents_and_self()
|
||||||
|
assert queries_count_fourth == queries_count_second + 1
|
||||||
|
|
||||||
# check footer doesn't get duplicated in real index children
|
# check footer doesn't get duplicated in real index children
|
||||||
page6 = Page(title='Sixth', slug='sixth', template_name='standard', parent=page_index)
|
page6 = Page(title='Sixth', slug='sixth', template_name='standard', parent=page_index)
|
||||||
|
|
Loading…
Reference in New Issue