diff --git a/doc/api/resources/subevents.rst b/doc/api/resources/subevents.rst index b71b238da3..11648c8611 100644 --- a/doc/api/resources/subevents.rst +++ b/doc/api/resources/subevents.rst @@ -75,6 +75,10 @@ last_modified datetime Last modificati The ``available_from``/``available_until`` attributes have been added to ``item_price_overrides`` and ``variation_price_overrides``. +.. versionchanged:: 4.15 + + The ``search`` query parameter has been added to filter sub-events by their name or location in any language. + Endpoints --------- @@ -147,6 +151,7 @@ Endpoints :query is_future: If set to ``true`` (``false``), only events that happen currently or in the future are (not) returned. :query is_past: If set to ``true`` (``false``), only events that are over are (not) 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. :param organizer: The ``slug`` field of a valid organizer :param event: The ``slug`` field of the main event :query datetime modified_since: Only return objects that have changed since the given date. Be careful: This does not diff --git a/src/pretix/api/views/event.py b/src/pretix/api/views/event.py index ddbd4f5592..e5b482d0d5 100644 --- a/src/pretix/api/views/event.py +++ b/src/pretix/api/views/event.py @@ -332,6 +332,7 @@ with scopes_disabled(): ends_after = django_filters.rest_framework.IsoDateTimeFilter(method='ends_after_qs') modified_since = django_filters.IsoDateTimeFilter(field_name='last_modified', lookup_expr='gte') sales_channel = django_filters.rest_framework.CharFilter(method='sales_channel_qs') + search = django_filters.rest_framework.CharFilter(method='search_qs') class Meta: model = SubEvent @@ -367,6 +368,12 @@ with scopes_disabled(): def sales_channel_qs(self, queryset, name, value): return queryset.filter(event__sales_channels__contains=value) + def search_qs(self, queryset, name, value): + return queryset.filter( + Q(name__icontains=i18ncomp(value)) + | Q(location__icontains=i18ncomp(value)) + ) + class SubEventViewSet(ConditionalListView, viewsets.ModelViewSet): serializer_class = SubEventSerializer diff --git a/src/tests/api/test_subevents.py b/src/tests/api/test_subevents.py index bc9176c676..03846183f5 100644 --- a/src/tests/api/test_subevents.py +++ b/src/tests/api/test_subevents.py @@ -167,6 +167,14 @@ def test_subevent_list_filter(token_client, organizer, event, subevent): assert resp.status_code == 200 assert resp.data['count'] == 0 + resp = token_client.get('/api/v1/organizers/{}/events/{}/subevents/?search=Foobar'.format(organizer.slug, event.slug)) + assert resp.status_code == 200 + assert resp.data['count'] == 1 + + resp = token_client.get('/api/v1/organizers/{}/events/{}/subevents/?search=Barfoo'.format(organizer.slug, event.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):