Skip to content

Commit

Permalink
#343 Drop redundant logic from siblings fetching. High level arch for…
Browse files Browse the repository at this point in the history
… breadcrumbs
  • Loading branch information
duker33 committed Sep 18, 2019
1 parent cda2817 commit bb2ad79
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 23 deletions.
3 changes: 3 additions & 0 deletions pages/logic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .page import *

__all__ = ['page']
43 changes: 43 additions & 0 deletions pages/logic/page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import typing

from pages import models


class Page:
def __init__(self, model: models.Page):
# "record" is much more good field name, i suppose.
# But "model" is Django standard.
self.model = model

def breadcrumbs(self) -> 'Breadcrumbs':
pass

@property
def siblings(self) -> models.PageQuerySet:
return self.model.parent.children.exclude(id=self.model.id)


# @todo #343:60m Implement Breadcrumbs class.
# Use it instead of monolithic logic at the `breadcrumbs_with_siblings`.
# Create Breadcrumb class or named tuple to specify crumb data structure.
class Breadcrumbs:
def __init__(self, page_model: models.Page):
self.model = page_model

def query(self, include_self: bool) -> models.PageQuerySet:
return (
self.model
.get_ancestors(include_self)
.select_related(self.model.related_model_name)
.active()
)

def list(self, include_self=False) -> typing.List[typing.Tuple[str, str]]:
"""Breadcrumbs list consists of current page ancestors."""
return [
(crumb.display_menu_title, crumb.url)
for crumb in self.query(include_self).iterator()
]

def list_with_self(self) -> list:
return self.list(include_self=True)
30 changes: 7 additions & 23 deletions pages/templatetags/pages_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.conf import settings
from django.core.urlresolvers import reverse

from pages import logic
from pages.models import CustomPage, FlatPage, Page

register = template.Library()
Expand All @@ -28,21 +29,6 @@ def breadcrumbs(page: Page, separator='', base_url=''):
def breadcrumbs_with_siblings(
page: Page, separator='', base_url='', include_self=False
):
def get_siblings(page):
def is_node(page):
return hasattr(page.model, 'children')

if not is_node(page):
return []

siblings = page.get_siblings().select_related(page.related_model_name)

return [
sibling
for sibling in siblings
if is_node(sibling)
]

def get_ancestors_crumbs() -> list:
ancestors_query = (
page
Expand All @@ -56,16 +42,14 @@ def get_ancestors_crumbs() -> list:

catalog, *ancestors = ancestors_query

siblings = [
get_siblings(ancestor)
for ancestor in ancestors
]

return [
(catalog.display_menu_title, catalog.url, []),
*[
(crumb.display_menu_title, crumb.url, crumb_links)
for crumb, crumb_links in zip(ancestors, siblings)
(
crumb.display_menu_title,
crumb.url,
list(logic.Page(page).siblings)
) for crumb in ancestors
],
]

Expand All @@ -74,7 +58,7 @@ def get_ancestors_crumbs() -> list:
crumbs_list = [
(index.display_menu_title, index.url, []) if index else ('Main', '/', []),
*get_ancestors_crumbs(),
(page.display_menu_title, '', get_siblings(page))
(page.display_menu_title, '', logic.Page(page).siblings)
]

return {
Expand Down
Empty file added tests/pages/logic/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions tests/pages/logic/test_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.test import TestCase

from pages import models


class PageTests(TestCase):
fixtures = ['catalog.json']

@property
def page(self):
return (
models.Page.objects
.active()
.filter(type=models.Page.MODEL_TYPE)
.exclude(parent=None)
.exclude(parent=models.CustomPage.objects.get(slug='catalog'))
.first()
)

def test_breadcrumbs(self):
...

0 comments on commit bb2ad79

Please sign in to comment.