diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 383cab539..b662c0c0c 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -159,6 +159,10 @@ last_modified datetime Last modificati The ``search`` query parameter has been added. +.. versionchanged:: 3.11 + + The ``exclude`` query parameter has been added. + .. _order-position-resource: @@ -485,6 +489,7 @@ List of all orders recommend using this in combination with ``testmode=false``, since test mode orders can vanish at any time and you will not notice it using this method. :query datetime created_since: Only return orders that have been created since the given date. + :query string exclude: Exclude a field from the output, e.g. ``fees`` or ``positions.downloads``. Can be used as a performance optimization. Can be passed multiple times. :param organizer: The ``slug`` field of the organizer to fetch :param event: The ``slug`` field of the event to fetch :resheader X-Page-Generated: The server time at the beginning of the operation. If you're using this API to fetch diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index 2c0417823..29326ec7a 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -376,6 +376,14 @@ class OrderSerializer(I18nAwareModelSerializer): if not self.context['request'].query_params.get('pdf_data', 'false') == 'true': self.fields['positions'].child.fields.pop('pdf_data') + for exclude_field in self.context['request'].query_params.getlist('exclude'): + p = exclude_field.split('.') + if p[0] in self.fields: + if len(p) == 1: + del self.fields[p[0]] + elif len(p) == 2: + self.fields[p[0]].child.fields.pop(p[1]) + def validate_locale(self, l): if l not in set(k for k in self.instance.event.settings.locales): raise ValidationError('"{}" is not a supported locale for this event.'.format(l)) diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py index 74b2682fc..846c13dad 100644 --- a/src/pretix/api/views/order.py +++ b/src/pretix/api/views/order.py @@ -121,16 +121,19 @@ class OrderViewSet(viewsets.ModelViewSet): return ctx def get_queryset(self): - if self.request.query_params.get('include_canceled_fees', 'false') == 'true': - fqs = OrderFee.all - else: - fqs = OrderFee.objects - qs = self.request.event.orders.prefetch_related( - Prefetch('fees', queryset=fqs.all()), - 'payments', 'refunds', 'refunds__payment' - ).select_related( - 'invoice_address' - ) + qs = self.request.event.orders + if 'fees' not in self.request.GET.getlist('exclude'): + if self.request.query_params.get('include_canceled_fees', 'false') == 'true': + fqs = OrderFee.all + else: + fqs = OrderFee.objects + qs = qs.prefetch_related(Prefetch('fees', queryset=fqs.all())) + if 'payments' not in self.request.GET.getlist('exclude'): + qs = qs.prefetch_related('payments') + if 'refunds' not in self.request.GET.getlist('exclude'): + qs = qs.prefetch_related('refunds', 'refunds__payment') + if 'invoice_address' not in self.request.GET.getlist('exclude'): + qs = qs.select_related('invoice_address') if self.request.query_params.get('include_canceled_positions', 'false') == 'true': opq = OrderPosition.all