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
|
||||
|
||||
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 = (
|
||||
attr_ids = [a.id for a in attributes]
|
||||
raw_vals = (
|
||||
AttributeValue.objects.annotate(value_length=Length("value"))
|
||||
.filter(attribute=attr, product__category=obj, value_length__lte=30)
|
||||
.values_list("value", flat=True)
|
||||
.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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue