diff --git a/doc/api/resources/subevents.rst b/doc/api/resources/subevents.rst index 89c24cee0c..544e2af395 100644 --- a/doc/api/resources/subevents.rst +++ b/doc/api/resources/subevents.rst @@ -68,6 +68,10 @@ last_modified datetime Last modificati The ``date_from_before``, ``date_from_after``, ``date_to_before``, and ``date_to_after`` query parameters have been added. +.. versionchanged:: 2023.8.0 + + For the organizer-wide endpoint, the ``search`` query parameter has been modified to filter sub-events by their parent events slug too. + Endpoints --------- @@ -472,6 +476,7 @@ Endpoints :query date_to_after: If set to a date and time, only events that have an end date and end at or after the given time are returned. :query date_to_before: If set to a date and time, only events that have an end date and end at or before the given time are returned. :query ends_after: If set to a date and time, only events that happen during of after the given time are returned. + :query search: Only return events matching a given search query. :query sales_channel: If set to a sales channel identifier, the response will only contain subevents from events available on this sales channel. :param organizer: The ``slug`` field of a valid organizer :param event: The ``slug`` field of the event to fetch diff --git a/src/pretix/api/views/event.py b/src/pretix/api/views/event.py index 772a71f6c2..08a516fd6a 100644 --- a/src/pretix/api/views/event.py +++ b/src/pretix/api/views/event.py @@ -381,16 +381,29 @@ with scopes_disabled(): | Q(location__icontains=i18ncomp(value)) ) + class OrganizerSubEventFilter(SubEventFilter): + def search_qs(self, queryset, name, value): + return queryset.filter( + Q(name__icontains=i18ncomp(value)) + | Q(event__slug__icontains=value) + | Q(location__icontains=i18ncomp(value)) + ) + class SubEventViewSet(ConditionalListView, viewsets.ModelViewSet): serializer_class = SubEventSerializer queryset = SubEvent.objects.none() write_permission = 'can_change_event_settings' filter_backends = (DjangoFilterBackend, TotalOrderingFilter) - filterset_class = SubEventFilter ordering = ('date_from',) ordering_fields = ('id', 'date_from', 'last_modified') + @property + def filterset_class(self): + if getattr(self.request, 'event', None): + return SubEventFilter + return OrganizerSubEventFilter + def get_queryset(self): if getattr(self.request, 'event', None): qs = self.request.event.subevents diff --git a/src/tests/api/test_subevents.py b/src/tests/api/test_subevents.py index e46e58ea66..569ba4dd75 100644 --- a/src/tests/api/test_subevents.py +++ b/src/tests/api/test_subevents.py @@ -207,6 +207,53 @@ def test_subevent_list_filter(token_client, organizer, event, subevent): assert resp.data['count'] == 0 +@pytest.mark.django_db +def test_all_subevents_list_filter(token_client, organizer, event, subevent): + resp = token_client.get('/api/v1/organizers/{}/subevents/?attr[type]=Workshop'.format(organizer.slug)) + assert resp.status_code == 200 + assert resp.data['count'] == 1 + + resp = token_client.get('/api/v1/organizers/{}/subevents/?attr[type]=Conference'.format(organizer.slug)) + assert resp.status_code == 200 + assert resp.data['count'] == 0 + + resp = token_client.get('/api/v1/organizers/{}/subevents/?search=Foobar'.format(organizer.slug)) + assert resp.status_code == 200 + assert resp.data['count'] == 1 + + resp = token_client.get('/api/v1/organizers/{}/subevents/?search=Barfoo'.format(organizer.slug)) + assert resp.status_code == 200 + assert resp.data['count'] == 0 + + resp = token_client.get('/api/v1/organizers/{}/subevents/?search=dummy'.format(organizer.slug)) + assert resp.status_code == 200 + assert resp.data['count'] == 1 + + resp = token_client.get( + '/api/v1/organizers/{}/subevents/?date_from_after=2017-12-27T10:00:00Z'.format(organizer.slug) + ) + assert resp.status_code == 200 + assert resp.data['count'] == 1 + + resp = token_client.get( + '/api/v1/organizers/{}/subevents/?date_from_after=2017-12-27T10:00:01Z'.format(organizer.slug) + ) + assert resp.status_code == 200 + assert resp.data['count'] == 0 + + resp = token_client.get( + '/api/v1/organizers/{}/subevents/?date_from_before=2017-12-27T10:00:00Z'.format(organizer.slug) + ) + assert resp.status_code == 200 + assert resp.data['count'] == 1 + + resp = token_client.get( + '/api/v1/organizers/{}/subevents/?date_from_before=2017-12-27T09:59:00Z'.format(organizer.slug) + ) + assert resp.status_code == 200 + assert resp.data['count'] == 0 + + @pytest.mark.django_db def test_subevent_create(team, token_client, organizer, event, subevent, meta_prop, item): meta_prop.allowed_values = "Conference\nWorkshop"