Features: 1) Optimize retrieval of filterable attributes by grouping attribute values and reducing query overhead;
Fixes: 1) Handle `user` lookup more robustly using `getattr`; 2) Prevent redundant list creation in distinct value processing; Extra: 1) Use consistent cache key variable; 2) Improve code readability with `defaultdict` for grouping; 3) Minor cleanup and formatting enhancements; 4) Remove unnecessary attribute redefinitions.
This commit is contained in:
parent
82a11dfc7e
commit
67c18fc8d2
1 changed files with 25 additions and 21 deletions
|
|
@ -75,42 +75,46 @@ class CategoryDetailSerializer(ModelSerializer):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_filterable_attributes(self, obj: Category) -> list[dict]:
|
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:
|
if filterable_results:
|
||||||
return filterable_results
|
return filterable_results
|
||||||
|
|
||||||
request: Request | None = self.context.get("request")
|
request = self.context.get("request")
|
||||||
user: User | AnonymousUser | None = getattr(request, "user") # noqa: B009
|
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:
|
attr_ids = [a.id for a in attributes]
|
||||||
user = AnonymousUser()
|
raw_vals = (
|
||||||
|
AttributeValue.objects.annotate(value_length=Length("value"))
|
||||||
attributes = obj.attributes.all() if user.has_perm("view_attribute") else obj.attributes.filter(is_active=True)
|
.filter(
|
||||||
|
attribute_id__in=attr_ids,
|
||||||
for attr in attributes:
|
product__category=obj,
|
||||||
distinct_vals = (
|
value_length__lte=30,
|
||||||
AttributeValue.objects.annotate(value_length=Length("value"))
|
|
||||||
.filter(attribute=attr, product__category=obj, value_length__lte=30)
|
|
||||||
.values_list("value", flat=True)
|
|
||||||
.distinct()
|
|
||||||
)
|
)
|
||||||
|
.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(
|
filterable_results.append(
|
||||||
{
|
{
|
||||||
"attribute_name": attr.name,
|
"attribute_name": attr.name,
|
||||||
"possible_values": distinct_vals_list,
|
"possible_values": slice_vals,
|
||||||
"value_type": attr.value_type,
|
"value_type": attr.value_type,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if user is None:
|
|
||||||
user = AnonymousUser()
|
|
||||||
|
|
||||||
if not user.has_perm("view_attribute"):
|
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
|
return filterable_results
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue