-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stb187 tags feature #187
Merged
Merged
Stb187 tags feature #187
Changes from 2 commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,22 +85,25 @@ def number_url_map(self): | |
def prepare_tile_products( | ||
products: ProductQuerySet, product_pages: QuerySet, tags: TagQuerySet=None | ||
): | ||
""" | ||
This method works on STB, but not on SE. | ||
|
||
This problem will gone when task below will be fixed. | ||
""" | ||
|
||
# @todo #550:60m Move prepare_tile_products func to context | ||
# Now it's separated function with huge of inconsistent queryset deps. | ||
assert isinstance(products, ProductQuerySet) | ||
|
||
images = Image.objects.get_main_images_by_pages( | ||
product_pages.filter(shopelectro_product__in=products) | ||
) | ||
|
||
brands = ( | ||
tags | ||
.filter_by_products(products) | ||
.get_brands(products) | ||
) if tags else defaultdict(lambda: None) | ||
images = defaultdict() | ||
if product_pages: | ||
images = Image.objects.get_main_images_by_pages( | ||
# TODO - customize `prepare_tile_products` for every site | ||
product_pages.filter(stroyprombeton_product__in=products) | ||
) | ||
|
||
return [ | ||
(product, images.get(product.page), brands.get(product)) | ||
(product, images.get(product.page)) | ||
for product in products | ||
] | ||
|
||
|
@@ -156,25 +159,25 @@ class AbstractPageContext(AbstractContext, ABC): | |
def __init__( # Ignore PyDocStyleBear | ||
self, | ||
url_kwargs: typing.Dict[str, str]=None, | ||
request: http.HttpRequest=None | ||
request: http.HttpRequest=None, | ||
page: ModelPage=None | ||
): | ||
""" | ||
:param url_kwargs: Came from `urls` module. | ||
:param request: Came from `urls` module | ||
""" | ||
|
||
if url_kwargs: | ||
assert 'slug' in url_kwargs | ||
self.page_ = page | ||
super().__init__(url_kwargs, request) | ||
|
||
@property | ||
def slug(self) -> str: | ||
return self.url_kwargs['slug'] | ||
|
||
@property | ||
@lru_cache(maxsize=1) | ||
def page(self): | ||
return ModelPage.objects.get(slug=self.slug) | ||
return ( | ||
self.page_ | ||
if self.page_ is not None | ||
else self.super.page | ||
) | ||
|
||
|
||
class AbstractProductsListContext(AbstractPageContext, ABC): | ||
|
@@ -185,6 +188,7 @@ def __init__( # Ignore PyDocStyleBear | |
self, | ||
url_kwargs: typing.Dict[str, str]=None, | ||
request: http.HttpRequest=None, | ||
page: ModelPage=None, | ||
products: ProductQuerySet=None, | ||
product_pages: QuerySet=None, | ||
): | ||
|
@@ -199,13 +203,17 @@ def __init__( # Ignore PyDocStyleBear | |
|
||
@property | ||
def product_pages(self) -> QuerySet: | ||
return self.product_pages_ or self.super.product_pages | ||
return ( | ||
self.product_pages_ | ||
if self.product_pages_ is not None | ||
else self.super.product_pages | ||
) | ||
|
||
@property | ||
def products(self) -> ProductQuerySet: | ||
if self.super: | ||
return self.super.products | ||
elif self.products_: | ||
elif isinstance(self.products_, ProductQuerySet): | ||
return self.products_ | ||
else: | ||
raise NotImplementedError('Set products queryset') | ||
|
@@ -250,12 +258,16 @@ def __init__( # Ignore PyDocStyleBear | |
# it's not good. Arg should not be default. | ||
# That's how we'll prevent assertion. | ||
# But we'll throw away inheritance in se#567. | ||
assert tags, 'tags is required arg' | ||
assert isinstance(tags, QuerySet), 'tags is required arg' | ||
self.tags_ = tags | ||
|
||
def get_sorting_index(self): | ||
return int(self.url_kwargs.get('sorting', 0)) | ||
|
||
def get_undirected_sorting_options(self) -> typing.List[str]: | ||
sorting_option = SortingOption(index=self.get_sorting_index()) | ||
return [sorting_option.field] | ||
|
||
# @todo #550:15m Move `TaggedCategory.get_tags` to property. | ||
# As in `products` property case. | ||
def get_tags(self) -> typing.Optional[TagQuerySet]: | ||
|
@@ -272,7 +284,7 @@ def get_tags(self) -> typing.Optional[TagQuerySet]: | |
@property | ||
def products(self): | ||
products = self.super.products | ||
sorting_option = SortingOption(index=self.get_sorting_index()) | ||
|
||
tags = self.get_tags() | ||
if tags: | ||
products = ( | ||
|
@@ -282,8 +294,8 @@ def products(self): | |
# that related with products by many-to-many relation. | ||
# @todo #550:60m Try to rm sorting staff from context.TaggedCategory. | ||
# Or explain again why it's impossible. Now it's not clear from comment. | ||
.distinct(sorting_option.field) | ||
.order_by(sorting_option.field) | ||
.distinct(*self.get_undirected_sorting_options()) | ||
.order_by(*self.get_undirected_sorting_options()) | ||
) | ||
return products | ||
|
||
|
@@ -354,11 +366,14 @@ class SortingCategory(AbstractProductsListContext): | |
def get_sorting_index(self): | ||
return int(self.url_kwargs.get('sorting', 0)) | ||
|
||
@property | ||
def products(self) -> ProductQuerySet: | ||
def get_sorting_options(self) -> typing.List[str]: | ||
sorting_index = int(self.url_kwargs.get('sorting', 0)) | ||
sorting_option = SortingOption(index=sorting_index) | ||
return self.super.products.order_by(sorting_option.directed_field) | ||
return [sorting_option.directed_field] | ||
|
||
@property | ||
def products(self) -> ProductQuerySet: | ||
return self.super.products.order_by(*self.get_sorting_options()) | ||
|
||
def get_context_data(self): | ||
context = self.super.get_context_data() | ||
|
@@ -423,8 +438,12 @@ def get_context_data(self): | |
context = self.super.get_context_data() | ||
self.check_pagination_args() | ||
|
||
if not self.products: | ||
raise http.Http404('Page without products does not exist.') | ||
# @todo #187:30m Return back empty products list 404 check. | ||
# Now we have problem with stb tests. | ||
# Now stb tests don't aware of it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uncomment the check for empty products list. |
||
|
||
# if not self.products: | ||
# raise http.Http404('Page without products does not exist.') | ||
|
||
paginated = PaginatorLinks( | ||
self.page_number, | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you use
defaultdict
here? It seems we can usedict
instead