Features: 1) Add Prefetch import in filters.py; 2) Introduce filter_order_by method with custom ordering logic for Category model.
Fixes: 1) Replace `OrderingFilter` with `CharFilter` for `order_by` field in `CategoryFilter`. Extra: 1) Remove unused ordering configuration from `order_by` field; 2) Refactor ordering logic with prefetch-related optimization for children categories.
This commit is contained in:
parent
eecb4c9ec4
commit
d811d1e5fe
1 changed files with 31 additions and 8 deletions
|
|
@ -15,6 +15,7 @@ from django.db.models import (
|
|||
Value,
|
||||
When,
|
||||
Max,
|
||||
Prefetch,
|
||||
)
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.utils.http import urlsafe_base64_decode
|
||||
|
|
@ -382,14 +383,7 @@ class CategoryFilter(FilterSet):
|
|||
tags = CaseInsensitiveListFilter(field_name="tags__tag_name", label=_("Tags"))
|
||||
level = NumberFilter(field_name="level", lookup_expr="exact", label=_("Level"))
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
("priority", "priority"),
|
||||
("uuid", "uuid"),
|
||||
("name", "name"),
|
||||
("?", "random"),
|
||||
)
|
||||
)
|
||||
order_by = CharFilter(method="filter_order_by")
|
||||
|
||||
class Meta:
|
||||
model = Category
|
||||
|
|
@ -404,6 +398,35 @@ class CategoryFilter(FilterSet):
|
|||
"whole",
|
||||
]
|
||||
|
||||
def filter_order_by(self, queryset, _name, value):
|
||||
if not value:
|
||||
return queryset
|
||||
|
||||
desc = value.startswith("-")
|
||||
key = value.lstrip("-")
|
||||
|
||||
mapping = {
|
||||
"priority": "priority",
|
||||
"uuid": "uuid",
|
||||
"name": "name",
|
||||
"?": "random",
|
||||
}
|
||||
field = mapping.get(key)
|
||||
if field is None:
|
||||
return queryset
|
||||
|
||||
if field == "?":
|
||||
parent_order = "?"
|
||||
child_order = "?"
|
||||
else:
|
||||
parent_order = f"-{field}" if desc else field
|
||||
child_order = parent_order
|
||||
|
||||
qs = queryset.order_by(parent_order)
|
||||
children_qs = Category.objects.all().order_by(child_order)
|
||||
|
||||
return qs.prefetch_related(Prefetch("children", queryset=children_qs))
|
||||
|
||||
def filter_name(self, queryset, _name, value):
|
||||
search_results = process_query(query=value, request=self.request)["categories"]
|
||||
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
|
||||
|
|
|
|||
Loading…
Reference in a new issue