From d25407e3b4a2a3f278200538b7a09ca8905fbca3 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 24 Apr 2018 18:25:57 +0200 Subject: [PATCH] API: Add fuzzy search to order positions API --- doc/api/resources/checkinlists.rst | 5 +++-- doc/api/resources/orders.rst | 5 +++-- src/pretix/api/views/order.py | 10 ++++++++++ src/tests/api/test_orders.py | 13 +++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/doc/api/resources/checkinlists.rst b/doc/api/resources/checkinlists.rst index b4a7504b3d..f0e83bd4c5 100644 --- a/doc/api/resources/checkinlists.rst +++ b/doc/api/resources/checkinlists.rst @@ -257,8 +257,8 @@ Order position endpoints .. versionchanged:: 1.15 The order positions endpoint has been extended by the filter queries ``item__in``, ``variation__in``, - ``order__status__in``, ``subevent__in``, and ``addon_to__in``. The search for attendee names and order codes is now - case-insensitive. + ``order__status__in``, ``subevent__in``, ``addon_to__in``, and ``search``. The search for attendee names and order + codes is now case-insensitive. .. http:get:: /api/v1/organizers/(organizer)/events/(event)/checkinlists/(list)/positions/ @@ -331,6 +331,7 @@ Order position endpoints ``order__datetime``, ``positionid``, ``attendee_name``, ``last_checked_in`` and ``order__email``. Default: ``attendee_name,positionid`` :query string order: Only return positions of the order with the given order code + :query string search: Fuzzy search matching the attendee name, order code, invoice address name as well as to the beginning of the secret. :query integer item: Only return positions with the purchased item matching the given ID. :query integer item__in: Only return positions with the purchased item matching one of the given comma-separated IDs. :query integer variation: Only return positions with the purchased item variation matching the given ID. diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 81970dc6b5..c4ee9713eb 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -616,8 +616,8 @@ Order position endpoints .. versionchanged:: 1.15 The order positions endpoint has been extended by the filter queries ``item__in``, ``variation__in``, - ``order__status__in``, ``subevent__in``, and ``addon_to__in``. The search for attendee names and order codes is now - case-insensitive. + ``order__status__in``, ``subevent__in``, ``addon_to__in`` and ``search``. The search for attendee names and order + codes is now case-insensitive. .. http:get:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/ @@ -690,6 +690,7 @@ Order position endpoints ``order__datetime``, ``positionid``, ``attendee_name``, and ``order__status``. Default: ``order__datetime,positionid`` :query string order: Only return positions of the order with the given order code + :query string search: Fuzzy search matching the attendee name, order code, invoice address name as well as to the beginning of the secret. :query integer item: Only return positions with the purchased item matching the given ID. :query integer item__in: Only return positions with the purchased item matching one of the given comma-separated IDs. :query integer variation: Only return positions with the purchased item variation matching the given ID. diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py index 41413f8689..cc56444f61 100644 --- a/src/pretix/api/views/order.py +++ b/src/pretix/api/views/order.py @@ -214,6 +214,16 @@ class OrderPositionFilter(FilterSet): order = django_filters.CharFilter(name='order', lookup_expr='code__iexact') has_checkin = django_filters.rest_framework.BooleanFilter(method='has_checkin_qs') attendee_name = django_filters.CharFilter(method='attendee_name_qs') + search = django_filters.CharFilter(method='search_qs') + + def search_qs(self, queryset, name, value): + return queryset.filter( + Q(secret__istartswith=value) + | Q(attendee_name__icontains=value) + | Q(addon_to__attendee_name__icontains=value) + | Q(order__code__istartswith=value) + | Q(order__invoice_address__name__icontains=value) + ) def has_checkin_qs(self, queryset, name, value): return queryset.filter(checkins__isnull=not value) diff --git a/src/tests/api/test_orders.py b/src/tests/api/test_orders.py index 084987b52d..050530c2eb 100644 --- a/src/tests/api/test_orders.py +++ b/src/tests/api/test_orders.py @@ -266,6 +266,19 @@ def test_orderposition_list(token_client, organizer, event, order, item, subeven '/api/v1/organizers/{}/events/{}/orderpositions/?secret=abc123'.format(organizer.slug, event.slug)) assert [] == resp.data['results'] + resp = token_client.get( + '/api/v1/organizers/{}/events/{}/orderpositions/?search=FO'.format(organizer.slug, event.slug)) + assert [res] == resp.data['results'] + resp = token_client.get( + '/api/v1/organizers/{}/events/{}/orderpositions/?search=z3fsn8j'.format(organizer.slug, event.slug)) + assert [res] == resp.data['results'] + resp = token_client.get( + '/api/v1/organizers/{}/events/{}/orderpositions/?search=Peter'.format(organizer.slug, event.slug)) + assert [res] == resp.data['results'] + resp = token_client.get( + '/api/v1/organizers/{}/events/{}/orderpositions/?search=5f4h6w'.format(organizer.slug, event.slug)) + assert [] == resp.data['results'] + resp = token_client.get( '/api/v1/organizers/{}/events/{}/orderpositions/?order=FOO'.format(organizer.slug, event.slug)) assert [res] == resp.data['results']