This commit is contained in:
Mira Weller
2024-07-23 11:34:40 +02:00
parent c3635162ec
commit 4ff6e47387
4 changed files with 75 additions and 15 deletions
View File
+53 -6
View File
@@ -52,7 +52,7 @@ from pretix.api.serializers import (
from pretix.api.serializers.i18n import I18nAwareModelSerializer
from pretix.api.serializers.settings import SettingsSerializer
from pretix.base.models import (
Device, Event, SalesChannel, TaxRule, TeamAPIToken, Seat,
Device, Event, SalesChannel, TaxRule, TeamAPIToken, Seat, CartPosition, Voucher,
)
from pretix.base.models.event import SubEvent
from pretix.base.models.items import (
@@ -971,20 +971,67 @@ class ItemMetaPropertiesSerializer(I18nAwareModelSerializer):
fields = ('id', 'name', 'default', 'required', 'allowed_values')
def prefetch_by_id(items, manager, id_attr, id_filter, target_attr):
"""
Prefetches a related object on each item in the given list of items by searching by id or another
unique field. The id value is read from the attribute on item specified in `id_attr`, searched on manager by the
field specified in `id_filter`, and the resulting prefetched model object is stored into `target_attr` on the item.
"""
ids = [getattr(item, id_attr) for item in items if getattr(item, id_attr)]
if ids:
result = manager.order_by(id_filter).distinct(id_filter).in_bulk(id_list=ids, field_name=id_filter)
for item in items:
setattr(item, target_attr, result.get(getattr(item, id_attr)))
class SeatSerializer(I18nAwareModelSerializer):
order = serializers.CharField()
cart = serializers.IntegerField()
voucher = serializers.IntegerField()
order = serializers.CharField(source='order_code')
cartposition = serializers.IntegerField(source='cartposition_id')
voucher = serializers.IntegerField(source='voucher_id')
class Meta:
model = Seat
read_only_fields = (
'id', 'subevent', 'zone_name', 'row_name', 'row_label',
'seat_number', 'seat_label', 'seat_guid', 'product', 'sorting_rank', 'x', 'y',
'order', 'cart', 'voucher',
'order', 'cartposition', 'voucher',
)
fields = (
'id', 'subevent', 'zone_name', 'row_name', 'row_label',
'seat_number', 'seat_label', 'seat_guid', 'product', 'blocked', 'sorting_rank', 'x', 'y',
'order', 'cart', 'voucher',
'order', 'cartposition', 'voucher',
)
def prefetch_expanded_data(self, items, expand_fields, event):
if 'order' in expand_fields:
prefetch_by_id(items, event.organizer.orders.prefetch_related('positions'), 'order_code', 'code', 'order')
if 'cartposition' in expand_fields:
prefetch_by_id(items, CartPosition.objects, 'cartposition_id', 'id', 'cartposition')
if 'voucher' in expand_fields:
prefetch_by_id(items, Voucher.objects, 'voucher_id', 'id', 'voucher')
def __init__(self, instance, *args, **kwargs):
if not kwargs.get('data'):
self.prefetch_expanded_data(instance if hasattr(instance, '__iter__') else [instance],
kwargs['context']['expand_fields'],
kwargs['context']['order_context']['event'])
super().__init__(instance, *args, **kwargs)
if 'order' in self.context['expand_fields']:
from pretix.api.serializers.order import OrderSerializer
self.fields['order'] = OrderSerializer(read_only=True, context=self.context['order_context'])
try:
del self.fields['order'].fields['positions'].child.fields['seat']
except KeyError:
pass
if 'cartposition' in self.context['expand_fields']:
from pretix.api.serializers.cart import CartPositionSerializer
self.fields['cartposition'] = CartPositionSerializer(read_only=True)
del self.fields['cartposition'].fields['seat']
if 'voucher' in self.context['expand_fields']:
from pretix.api.serializers.voucher import VoucherSerializer
self.fields['voucher'] = VoucherSerializer(read_only=True)
del self.fields['voucher'].fields['seat']
+19 -6
View File
@@ -673,9 +673,8 @@ class SeatViewSet(ConditionalListView, viewsets.ModelViewSet):
serializer_class = SeatSerializer
queryset = Seat.objects.none()
write_permission = 'can_change_event_settings'
filter_backends = [DjangoFilterBackend]
filterset_fields = ['zone_name', 'row_name', 'row_label', 'seat_number', 'seat_label',
'seat_guid', 'blocked',]
filter_backends = (DjangoFilterBackend,)
filterset_fields = ('zone_name', 'row_name', 'row_label', 'seat_number', 'seat_label', 'seat_guid', 'blocked',)
def get_queryset(self):
if self.request.event.has_subevents and 'subevent' in self.request.resolver_match.kwargs:
@@ -683,11 +682,25 @@ class SeatViewSet(ConditionalListView, viewsets.ModelViewSet):
subevent = self.request.event.subevents.get(pk=self.request.resolver_match.kwargs['subevent'])
except SubEvent.DoesNotExist:
raise NotFound('Subevent not found')
return Seat.annotated(event_id=self.request.event.id, subevent=subevent, qs=subevent.seats.all(), annotate_ids=True)
qs = Seat.annotated(event_id=self.request.event.id, subevent=subevent, qs=subevent.seats.all(), annotate_ids=True)
elif not self.request.event.has_subevents and 'subevent' not in self.request.resolver_match.kwargs:
return Seat.annotated(event_id=self.request.event.id, subevent=None, qs=self.request.event.seats.all(), annotate_ids=True)
qs = Seat.annotated(event_id=self.request.event.id, subevent=None, qs=self.request.event.seats.all(), annotate_ids=True)
else:
raise NotFound
raise NotFound('Please use the subevent-specific endpoint' if self.request.event.has_subevents
else 'This event has no subevents')
return qs
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['expand_fields'] = self.request.query_params.getlist('expand')
ctx['order_context'] = {
'event': self.request.event,
'pdf_data': None,
'include': self.request.query_params.getlist('order_include'),
'exclude': self.request.query_params.getlist('order_exclude'),
}
return ctx
def perform_update(self, serializer):
super().perform_update(serializer)
+3 -3
View File
@@ -216,9 +216,9 @@ class Seat(models.Model):
cqs = cqs.exclude(cart_id=ignore_cart_id)
if annotate_ids:
qs_annotated = qs.annotate(
order=Subquery(opqs.values('order__code')),
cart=Subquery(cqs.values('id')),
voucher=Subquery(vqs.values('id')),
order_code=Subquery(opqs.values('order__code')),
cartposition_id=Subquery(cqs.values('id')),
voucher_id=Subquery(vqs.values('id')),
)
else:
qs_annotated = qs.annotate(