Skip to content
Snippets Groups Projects
Commit 639baa36 authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

fix: restore has_timeslots order criteria for episode endpoint

The has_timeslots order criteria worked until commit
435e72d5 removed it from the default
queryset. This was the right choice in general because the annotation is
relatively expensive. However, it ignored the use in the ordering
filter.

To get the best of both worlds:
* fast query speed for queries that don’t care about timeslots
* filtering/ordering based on timeslots

this commit implements conditional ordering filter annotations.

refs dashboard#359
parent 541e6540
Branches
No related tags found
No related merge requests found
Pipeline #9137 failed
......@@ -55,6 +55,18 @@ class IntegerInFilter(filters.BaseInFilter):
super().__init__(*args, **kwargs)
class AnnotatedOrderingFilter(filters.OrderingFilter):
def __init__(self, *args, **kwargs):
self._filter_annotation_map = kwargs.pop("filter_annotation_map", {})
super().__init__(*args, **kwargs)
def filter(self, qs, value):
for key, annotation in self._filter_annotation_map.items():
if key in value or f"-{key}" in value:
qs = qs.annotate(**{key: annotation})
return super().filter(qs, value)
class ShowOrderingFilter(filters.OrderingFilter):
def filter(self, qs: QuerySet, value):
if value in constants.EMPTY_VALUES:
......@@ -289,9 +301,15 @@ class TimeSlotFilterSet(filters.FilterSet):
]
episode_has_timeslots = Exists(models.TimeSlot.objects.filter(episode=OuterRef("pk")))
class EpisodeFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
order = filters.OrderingFilter(
order = AnnotatedOrderingFilter(
fields=["title", "id", "updated_at", "updated_by", "has_timeslots"],
filter_annotation_map={
"has_timeslots": episode_has_timeslots,
},
)
ids = IntegerInFilter(
field_name="id",
......@@ -310,7 +328,7 @@ class EpisodeFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
help_text="Return only episodes that belong to the specified timeslot(s).",
)
has_timeslots = StaticQueryBooleanFilter(
query=Exists(models.TimeSlot.objects.filter(episode=OuterRef("pk"))),
query=episode_has_timeslots,
label="Has timeslots",
help_text="Returns only timeslots that either have or have not any timeslots.",
)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment