Skip to content

Commit

Permalink
#550 Implement CatalogContext
Browse files Browse the repository at this point in the history
  • Loading branch information
duker33 committed Aug 31, 2018
1 parent 645782d commit 8d41122
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 17 deletions.
155 changes: 155 additions & 0 deletions shopelectro/context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"""
Contains view context classes.
Context is part of the View abstract layer in MTV paradigm.
It stands between urls and view functions.
Every context class is used via objects composition.
For example:
TODO - add example of objects composition
"""

import typing
from functools import lru_cache, partial

from django import http
from django.db.models import QuerySet
from django.conf import settings
from django.core.paginator import Paginator, InvalidPage
from django.shortcuts import render, get_object_or_404
from django.views.decorators.http import require_POST
from django_user_agents.utils import get_user_agent

from catalog.views import catalog
from images.models import Image
from pages import views as pages_views

from shopelectro import models
from shopelectro.views.helpers import set_csrf_cookie

from pages.models import ModelPage, Page


@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)
.get_brands(products)
)

return [
(product, images.get(product.page), brands.get(product))
for product in products
]


class ObjectsComposition:

super = object()

def __or__(self, other):
self.super = other


class AbstractContext(ObjectsComposition):

# TODO - raise not implemented here
# @property
# def request(self):
# raise NotImplemented()

# @property
# def page(self) -> Page:
# """Page from DB, that should be selected"""
# raise NotImplemented()

def get_context_data(self, **kwargs) -> dict:
raise NotImplemented()


class ProductsListContext(AbstractContext):
@property
def products(self) -> QuerySet:
raise NotImplemented()


# TODO - fork PageContext
class CategoryContext(ProductsListContext):

# TODO - annotate it
def __init__(self, slug, request):
self.slug = slug
self.request = request

@property
@lru_cache(maxsize=1)
def page(self):
return ModelPage.objects.get(slug=self.slug)

@property
@lru_cache(maxsize=1)
def products(self) -> QuerySet:
return models.Product.actives.get_category_descendants(
self.page.model
)

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')

group_tags_pairs = (
models.Tag.objects
.filter_by_products(self.products)
.get_group_tags_pairs()
)

return {
'products_data': merge_products_context(self.products),
'group_tags_pairs': group_tags_pairs,
# TODO add comment about view_type
'view_type': view_type,
}


# class TaggedCategoryContext:
# def products(tags):
# return self.super.products().and_aother_fetch(catalog)
#
# def get_context_data():
# return {
# **self.super.get_context_data(),
# ... # and something simple only about tags
# }
#
#
# class PaginatedCatalogContext:
# ...
#
#
# class DBTemplateContext:
# ...
#
#
# class CatalogView:
# def get_context_data(category_id, page_num):
# category = some_fetch(category_id)
# context = CatalogContext(category) | PaginatedCatalogContext(page_num)
# return context.get_context_data()
#
#
# class TaggedCatalogView:
# def get_context_data(category_id, page_num, tags):
# category = some_fetch(category_id)
# context = (
# CatalogContext(category)
# | PaginatedCatalogContext(page_num)
# | TaggedCatalogContext(tags)
# | DBTemplateContext(tags)
# )
# return context.get_context_data()
21 changes: 4 additions & 17 deletions shopelectro/views/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from images.models import Image
from pages import views as pages_views

from shopelectro import models
from shopelectro import context, models
from shopelectro.views.helpers import set_csrf_cookie

PRODUCTS_ON_PAGE_PC = 48
Expand Down Expand Up @@ -189,23 +189,10 @@ 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)
.get_group_tags_pairs()
)

context_ = context.CategoryContext(self.object.slug, self.request)
return {
**context,
'products_data': merge_products_context(products),
'group_tags_pairs': group_tags_pairs,
# TODO add comment about view_type
'view_type': view_type,
**super().get_context_data(**kwargs),
**context_.get_context_data(),
}


Expand Down

0 comments on commit 8d41122

Please sign in to comment.