diff --git a/core/serializers/detail.py b/core/serializers/detail.py index 302fb2c9..099eda60 100644 --- a/core/serializers/detail.py +++ b/core/serializers/detail.py @@ -75,42 +75,46 @@ class CategoryDetailSerializer(ModelSerializer): return None def get_filterable_attributes(self, obj: Category) -> list[dict]: - filterable_results = cache.get(f"{obj.uuid}_filterable_results", []) - + cache_key = f"{obj.uuid}_filterable_results" + filterable_results = cache.get(cache_key) if filterable_results: return filterable_results - request: Request | None = self.context.get("request") - user: User | AnonymousUser | None = getattr(request, "user") # noqa: B009 + request = self.context.get("request") + user = getattr(request, "user", AnonymousUser()) + attrs_qs = obj.attributes.all() if user.has_perm("view_attribute") else obj.attributes.filter(is_active=True) + attributes = list(attrs_qs) - if user is None: - user = AnonymousUser() - - attributes = obj.attributes.all() if user.has_perm("view_attribute") else obj.attributes.filter(is_active=True) - - for attr in attributes: - distinct_vals = ( - AttributeValue.objects.annotate(value_length=Length("value")) - .filter(attribute=attr, product__category=obj, value_length__lte=30) - .values_list("value", flat=True) - .distinct() + attr_ids = [a.id for a in attributes] + raw_vals = ( + AttributeValue.objects.annotate(value_length=Length("value")) + .filter( + attribute_id__in=attr_ids, + product__category=obj, + value_length__lte=30, ) + .values_list("attribute_id", "value") + .distinct() + ) - distinct_vals_list = list(distinct_vals)[0:128] if len(list(distinct_vals)) > 128 else list(distinct_vals) + grouped = defaultdict(list) + for attr_id, val in raw_vals: + grouped[attr_id].append(val) + filterable_results = [] + for attr in attributes: + vals = grouped.get(attr.id, []) + slice_vals = vals[:128] if len(vals) > 128 else vals filterable_results.append( { "attribute_name": attr.name, - "possible_values": distinct_vals_list, + "possible_values": slice_vals, "value_type": attr.value_type, } ) - if user is None: - user = AnonymousUser() - if not user.has_perm("view_attribute"): - cache.set(f"{obj.uuid}_filterable_results", filterable_results, 86400) + cache.set(cache_key, filterable_results, 86400) return filterable_results