diff --git a/shopelectro/context.py b/shopelectro/context.py index eceb304c..6022899a 100644 --- a/shopelectro/context.py +++ b/shopelectro/context.py @@ -62,16 +62,18 @@ def merge_products_context(products): class ObjectsComposition: - super = object() + super: 'ObjectsComposition' = None # TODO - resolve objects good piping - def __or__(self, other): - self.super = other - return self + def __or__(self, other: 'ObjectsComposition'): + other.super = self + return other class AbstractContext(ObjectsComposition): + super: 'AbstractContext' = None + def __init__( self, # TODO slug maybe part of url_kwargs @@ -108,7 +110,11 @@ def get_context_data(self) -> typing.Dict[str, typing.Any]: raise NotImplementedError +# TODO make it ABC or smth class ProductsListContext(AbstractContext): + + super: 'ProductsListContext' = None + @property def products(self) -> QuerySet: raise NotImplementedError @@ -188,12 +194,49 @@ def get_context_data(self): } +class DBTemplateContext(AbstractContext): + """Processes some page data fields as templates with each own context.""" + + @property + @lru_cache(maxsize=1) + def page(self): + page = self.super.page + context = self.get_super_context_data() + + def template_context(page, tag_titles, tags): + return { + 'page': page, + 'tag_titles': tag_titles, + 'tags': tags, + } + + tags = context['tags'] + if tags: + # TODO - move to QuerySet + tag_titles = models.serialize_tags_to_title(tags) + page.get_template_render_context = partial( + template_context, page, tag_titles, tags + ) + + return page + + @lru_cache(maxsize=1) + def get_super_context_data(self): + """Just for cache.""" + return self.super.get_context_data() + + @lru_cache(maxsize=1) + def get_context_data(self): + return { + **self.get_super_context_data(), + 'page': self.page, + } + + # class PaginatedCatalogContext: # ... # # -# class DBTemplateContext: -# ... # # # class CatalogView: diff --git a/shopelectro/models.py b/shopelectro/models.py index 427e0d83..1d2ca44f 100644 --- a/shopelectro/models.py +++ b/shopelectro/models.py @@ -326,6 +326,9 @@ def serialize_tags( type_delimiter: str, group_delimiter: str, ) -> str: + if not tags: + return '' + group_tags_map = tags.get_group_tags_pairs() _, tags_by_group = zip(*group_tags_map) diff --git a/shopelectro/views/catalog.py b/shopelectro/views/catalog.py index 7a102dbf..bda3cf8f 100644 --- a/shopelectro/views/catalog.py +++ b/shopelectro/views/catalog.py @@ -189,8 +189,12 @@ def get_products(self) -> QuerySet: def get_context_data(self, **kwargs): """Add sorting options and view_types in context.""" - context_ = context.TaggedCategoryContext() | context.CategoryContext( - self.object.slug, kwargs, self.request + context_ = ( + context.CategoryContext( + self.object.slug, self.kwargs, self.request + ) + | context.TaggedCategoryContext() + | context.DBTemplateContext() ) return { **super().get_context_data(**kwargs), @@ -198,43 +202,7 @@ def get_context_data(self, **kwargs): } -class DBContextCategoryPage(CategoryPage): - """Process db page data as db context.""" - - def get_tags(self) -> typing.Optional[models.TagQuerySet]: - - @lru_cache(maxsize=64) - def get_tags(request_tags_: str): - slugs = models.Tag.parse_url_tags(request_tags_) - return models.Tag.objects.filter(slug__in=slugs) - - request_tags = self.kwargs.get('tags') - if not request_tags: - return None - return get_tags(request_tags) - - def get_object(self, queryset=None): - page = super().get_object(queryset) - - def template_context(page, tag_titles, tags): - return { - 'page': page, - 'tag_titles': tag_titles, - 'tags': tags, - } - - tags = self.get_tags() - if tags: - # TODO - move to QuerySet - tag_titles = models.serialize_tags_to_title(tags) - page.get_template_render_context = partial( - template_context, page, tag_titles, tags - ) - - return page - - -class SortingCategoryPage(DBContextCategoryPage): +class SortingCategoryPage(CategoryPage): def get_products(self) -> QuerySet: sorting_index = int(self.kwargs.get('sorting', 0))