From 1dbb068becf8d97f1663918cac1341fe9736b596 Mon Sep 17 00:00:00 2001 From: duker Date: Wed, 29 Aug 2018 14:05:36 +0300 Subject: [PATCH] #550 Fork DBContextCatalogPage class --- shopelectro/tests/tests_views.py | 12 +++++++++++ shopelectro/urls.py | 8 +++---- shopelectro/views/catalog.py | 36 ++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/shopelectro/tests/tests_views.py b/shopelectro/tests/tests_views.py index e220188f..d8bbb05f 100644 --- a/shopelectro/tests/tests_views.py +++ b/shopelectro/tests/tests_views.py @@ -20,6 +20,7 @@ from django.utils.translation import ugettext as _ from shopelectro.models import Category, Product, Tag, TagGroup, TagQuerySet, serialize_tags_to_url +from shopelectro.views.catalog import merge_products_context from shopelectro.views.service import generate_md5_for_ya_kassa, YANDEX_REQUEST_PARAM @@ -74,6 +75,17 @@ def get_category_page( )) +class CatalogPage(BaseCatalogTestCase): + + def test_merge_product_cache(self): + """Context merging should cached.""" + products = Product.objects.all()[:2] + with self.assertNumQueries(7): + merge_products_context(products) + with self.assertNumQueries(0): + merge_products_context(products) + + class CatalogTags(BaseCatalogTestCase): # @todo #522:15m Move method `CatalogTags.create_doubled_tag` to test helpers. diff --git a/shopelectro/urls.py b/shopelectro/urls.py index d7d2c5cf..c9d07057 100644 --- a/shopelectro/urls.py +++ b/shopelectro/urls.py @@ -50,13 +50,13 @@ def cache_page(arg): # Ignore PyFlakesBear catalog_urls = [ # "category" group url(r'^categories/(?P[\w-]+)/$', - cached_2h(views.TaggedCategoryPage.as_view()), name='category'), + cached_2h(views.DBContextCategoryPage.as_view()), name='category'), url(r'^categories/(?P[\w-]+)/tags/(?P[\w_-]+)/$', - cached_2h(views.TaggedCategoryPage.as_view()), name='category'), + cached_2h(views.DBContextCategoryPage.as_view()), name='category'), url(r'^categories/(?P[\w-]+)/(?P[0-9]*)/$', - views.TaggedCategoryPage.as_view(), name='category'), + views.DBContextCategoryPage.as_view(), name='category'), url(r'^categories/(?P[\w-]+)/(?P[0-9]*)/tags/(?P[\w_-]+)/$', - views.TaggedCategoryPage.as_view(), name='category'), + views.DBContextCategoryPage.as_view(), name='category'), # "load more" group url(r'categories/(?P[\w-]+)/load-more/' r'(?P[0-9]+)/(?P[0-9]*)/$', diff --git a/shopelectro/views/catalog.py b/shopelectro/views/catalog.py index 81445e6f..9e3fa826 100644 --- a/shopelectro/views/catalog.py +++ b/shopelectro/views/catalog.py @@ -159,12 +159,14 @@ def get_context_data(self, **kwargs): } +# TODO - split to ProductImagesContext and ProductBrandContext @lru_cache(maxsize=64) def merge_products_context(products): images = Image.objects.get_main_images_by_pages( models.ProductPage.objects.filter(shopelectro_product__in=products) ) + # TODO - create product.get_brand instead brands = ( models.Tag.objects .filter_by_products(products) @@ -189,10 +191,11 @@ def get_products(self) -> QuerySet: def get_context_data(self, **kwargs): """Add sorting options and view_types in context.""" + # TODO take from dataclass or smth + view_type = self.request.session.get('view_type', 'tile') context = super().get_context_data(**kwargs) products = self.get_products() - group_tags_pairs = ( models.Tag.objects .filter_by_products(products) @@ -203,16 +206,17 @@ def get_context_data(self, **kwargs): **context, 'products_data': merge_products_context(products), 'group_tags_pairs': group_tags_pairs, + # TODO add comment about view_type + 'view_type': view_type, } -# @todo #550:60m Split TaggedCategoryPage class -# See details at parent task. class TaggedCategoryPage(CategoryPage): def get_sorting_index(self): return int(self.kwargs.get('sorting', 0)) + # TODO - test if it's cached def get_tags(self) -> typing.Optional[models.TagQuerySet]: @lru_cache(maxsize=64) @@ -239,13 +243,29 @@ def get_products(self): ) return products + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + tags = self.get_tags() + return { + **context, + 'tags': tags, + # TODO write comment about skip_canonical + 'skip_canonical': bool(tags), + } + + +class DBContextCategoryPage(TaggedCategoryPage): + """Process db page data as db context.""" + + def get_sorting_index(self): + return int(self.kwargs.get('sorting', 0)) + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) products_on_page = int(self.request.GET.get( 'step', get_products_count(self.request), )) page_number = int(self.request.GET.get('page', 1)) - view_type = self.request.session.get('view_type', 'tile') if ( page_number < 1 or @@ -262,12 +282,13 @@ def template_context(page, tag_titles, tags): 'tags': tags, } - tags = self.get_tags() + tags = super().get_tags() if tags: tag_titles = models.serialize_tags_to_title(tags) page = context['page'] page.get_template_render_context = partial( - template_context, page, tag_titles, tags) + template_context, page, tag_titles, tags + ) paginated_page = get_paginated_page_or_404(products, products_on_page, page_number) total_products = products.count() @@ -284,9 +305,6 @@ def template_context(page, tag_titles, tags): 'sorting_options': settings.CATEGORY_SORTING_OPTIONS.values(), 'limits': settings.CATEGORY_STEP_MULTIPLIERS, 'sort': self.get_sorting_index(), - 'tags': tags, - 'view_type': view_type, - 'skip_canonical': bool(tags), }