diff --git a/src/oscar_pg_search/filter_options/base_fields.py b/src/oscar_pg_search/filter_options/base_fields.py index 40c2530..5d3b1a3 100644 --- a/src/oscar_pg_search/filter_options/base_fields.py +++ b/src/oscar_pg_search/filter_options/base_fields.py @@ -1,5 +1,6 @@ from django import forms from oscar.core.loading import get_model +from django.core.cache import cache RangeProduct = get_model('offer', 'RangeProduct') @@ -11,6 +12,7 @@ class MultipleChoiceFieldBase(forms.MultipleChoiceField): widget = forms.SelectMultiple(attrs={'class': 'chosen-select'}) + fieldname: str def __init__(self, request_data, form, *args, request=None, **kwargs): super().__init__(required=False, *args, **kwargs) @@ -23,7 +25,12 @@ def initialize(self): """ This is running after the result was created by manager. """ - self.choices = self.get_choices() + path = self.manager.request.get_full_path() + key = f'{path}_product_filter_choices__{self.fieldname}' + partner = getattr(self.manager, 'main_partner', None) + if partner: + key = f'partner{partner.pk}_{key}' + self.choices = cache.get_or_set(key, self.get_choices) @property def query(self): @@ -40,7 +47,7 @@ class AttributeFieldBase(MultipleChoiceFieldBase): def __init__(self, attribute, *args, **kwargs): super().__init__(*args, label=attribute.name, **kwargs) self.attribute = attribute - self.fieldname = f'value_{attribute.type}' + self.fieldname = f'value_{self.attribute.code}' class ProductFieldBase(MultipleChoiceFieldBase): @@ -49,6 +56,7 @@ def __init__(self, code, *args, **kwargs): self.code = code self.field = Product.get_field(code) self.label = Product.get_field_label(self.field) + self.fieldname = code def clean_value(self, value): clean_func = { @@ -59,12 +67,6 @@ def clean_value(self, value): }.get(self.code, lambda x: x) return clean_func(value) - def initialize(self): - """ - This is running after the result was created by manager. - """ - self.choices = self.get_choices() - @property def query(self): return self.get_query() diff --git a/src/oscar_pg_search/postgres_search_handler.py b/src/oscar_pg_search/postgres_search_handler.py old mode 100644 new mode 100755 index d46f65f..b048f4d --- a/src/oscar_pg_search/postgres_search_handler.py +++ b/src/oscar_pg_search/postgres_search_handler.py @@ -10,6 +10,7 @@ from django.utils.safestring import mark_safe from django.db.models.functions.comparison import Coalesce from django.db import connection +from django.core.cache import cache from oscar.apps.catalogue.search_handlers import SimpleProductSearchHandler from oscar.core.loading import get_model @@ -88,8 +89,19 @@ def get_queryset(self): return qs + def get_paginator(self, *args, **kwargs): + paginator = super().get_paginator(*args, **kwargs) + partner_pk = self.request.user.partner.pk or 0 + path = self.request.get_full_path() + count = cache.get_or_set( + f'partner{partner_pk}_{path}_result_count', + lambda: paginator.count, + ) + setattr(paginator, 'count', count) + return paginator + def get_context_data(self, *, object_list=None, **kwargs): - context = SimpleProductSearchHandler.get_context_data(self, **kwargs) + context = super().get_context_data(object_list=object_list, **kwargs) search_params = '' if self.query_string: search_params += '&q=' + self.query_string @@ -102,11 +114,10 @@ def get_context_data(self, *, object_list=None, **kwargs): def get_search_context_data(self, context_object_name): self.context_object_name = context_object_name context = self.get_context_data(object_list=self.object_list) - self.get_context_data(object_list=self.object_list.filter(id=0)) - if context['page_obj']: + if 'page_obj' in context: context[context_object_name] = context['page_obj'].object_list else: - context[context_object_name] = self.object_list.filter(id=0) + context[context_object_name] = self.object_list.none() return context def search(self, qs, query_string): diff --git a/src/oscar_pg_search/utils.py b/src/oscar_pg_search/utils.py index d8060ea..cc287d1 100644 --- a/src/oscar_pg_search/utils.py +++ b/src/oscar_pg_search/utils.py @@ -12,13 +12,14 @@ class FilterManager: wishlist_as_link = False def __init__(self, request_data, qs, request=None): + self.request = request self.request_data = request_data self.qs = qs # Domain specific logic for creating Partner based options: if request and hasattr(request, 'partners'): - main_partner = getattr(request, 'partners')[0] - self.wishlist_as_link = main_partner.wishlist_as_link + self.main_partner = getattr(request, 'partners')[0] + self.wishlist_as_link = self.main_partner.wishlist_as_link self.filters = self.get_filters(request=request) self.result = self.get_result() self.initialize_filters()