From ddc94a8a1664d63191ba7c642ceb9855b66ab7e8 Mon Sep 17 00:00:00 2001 From: Richard Schreiber Date: Mon, 14 Aug 2023 15:11:13 +0200 Subject: [PATCH] Revert "Allow PDF variables to provide a bulk evaluation method (#3517)" This reverts commit 6ada83df9ab235d5b7d15cb80abd436a89819fce. --- src/pretix/api/serializers/order.py | 77 ++--------------------------- src/pretix/base/signals.py | 6 +-- 2 files changed, 6 insertions(+), 77 deletions(-) diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index 1765cb561d..b167fa5ecb 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -27,7 +27,6 @@ from decimal import Decimal import pycountry from django.conf import settings from django.core.files import File -from django.db import models from django.db.models import F, Q from django.utils.encoding import force_str from django.utils.timezone import now @@ -373,15 +372,11 @@ class PdfDataSerializer(serializers.Field): self.context['vars_images'] = get_images(self.context['event']) for k, f in self.context['vars'].items(): - if 'evaluate_bulk' in f: - # Will be evaluated later by our list serializers - res[k] = (f['evaluate_bulk'], instance) - else: - try: - res[k] = f['evaluate'](instance, instance.order, ev) - except: - logger.exception('Evaluating PDF variable failed') - res[k] = '(error)' + try: + res[k] = f['evaluate'](instance, instance.order, ev) + except: + logger.exception('Evaluating PDF variable failed') + res[k] = '(error)' if not hasattr(ev, '_cached_meta_data'): ev._cached_meta_data = ev.meta_data @@ -434,38 +429,6 @@ class PdfDataSerializer(serializers.Field): return res -class OrderPositionListSerializer(serializers.ListSerializer): - - def to_representation(self, data): - # We have a custom implementation of this method because PdfDataSerializer() might keep some elements unevaluated - # with a (callable, input) tuple. We'll loop over these entries and evaluate them bulk-wise to save on SQL queries. - - if isinstance(self.parent, OrderSerializer) and isinstance(self.parent.parent, OrderListSerializer): - # Do not execute our custom code because it will be executed by OrderListSerializer later for the - # full result set. - return super().to_representation(data) - - iterable = data.all() if isinstance(data, models.Manager) else data - - data = [] - evaluate_queue = defaultdict(list) - - for item in iterable: - entry = self.child.to_representation(item) - if "pdf_data" in entry: - for k, v in entry["pdf_data"].items(): - if isinstance(v, tuple) and callable(v[0]): - evaluate_queue[v[0]].append((v[1], entry, k)) - data.append(entry) - - for func, entries in evaluate_queue.items(): - results = func([item for (item, entry, k) in entries]) - for (item, entry, k), result in zip(entries, results): - entry["pdf_data"][k] = result - - return data - - class OrderPositionSerializer(I18nAwareModelSerializer): checkins = CheckinSerializer(many=True, read_only=True) answers = AnswerSerializer(many=True) @@ -477,7 +440,6 @@ class OrderPositionSerializer(I18nAwareModelSerializer): attendee_name = serializers.CharField(required=False) class Meta: - list_serializer_class = OrderPositionListSerializer model = OrderPosition fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts', 'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount', @@ -651,34 +613,6 @@ class OrderURLField(serializers.URLField): }) -class OrderListSerializer(serializers.ListSerializer): - - def to_representation(self, data): - # We have a custom implementation of this method because PdfDataSerializer() might keep some elements - # unevaluated with a (callable, input) tuple. We'll loop over these entries and evaluate them bulk-wise to - # save on SQL queries. - iterable = data.all() if isinstance(data, models.Manager) else data - - data = [] - evaluate_queue = defaultdict(list) - - for item in iterable: - entry = self.child.to_representation(item) - for p in entry.get("positions", []): - if "pdf_data" in p: - for k, v in p["pdf_data"].items(): - if isinstance(v, tuple) and callable(v[0]): - evaluate_queue[v[0]].append((v[1], p, k)) - data.append(entry) - - for func, entries in evaluate_queue.items(): - results = func([item for (item, entry, k) in entries]) - for (item, entry, k), result in zip(entries, results): - entry["pdf_data"][k] = result - - return data - - class OrderSerializer(I18nAwareModelSerializer): invoice_address = InvoiceAddressSerializer(allow_null=True) positions = OrderPositionSerializer(many=True, read_only=True) @@ -693,7 +627,6 @@ class OrderSerializer(I18nAwareModelSerializer): class Meta: model = Order - list_serializer_class = OrderListSerializer fields = ( 'code', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date', 'payment_provider', 'fees', 'total', 'comment', 'custom_followup_at', 'invoice_address', 'positions', 'downloads', diff --git a/src/pretix/base/signals.py b/src/pretix/base/signals.py index 90789ed00b..5c064b9c7e 100644 --- a/src/pretix/base/signals.py +++ b/src/pretix/base/signals.py @@ -683,16 +683,12 @@ dictionaries as values that contain keys like in the following example:: "product": { "label": _("Product name"), "editor_sample": _("Sample product"), - "evaluate": lambda orderposition, order, event: str(orderposition.item), - "evaluate_bulk": lambda orderpositions: [str(op.item) for op in orderpositions], + "evaluate": lambda orderposition, order, event: str(orderposition.item) } } The ``evaluate`` member will be called with the order position, order and event as arguments. The event might also be a subevent, if applicable. - -The ``evaluate_bulk`` member is optional but can significantly improve performance in some situations because you -can perform database fetches in bulk instead of single queries for every position. """