Add API endpoint /seats to event (Z#23159536) (#4321)

* add API endpoint /seats to event

* fix logging

* add Seat annotations

* add seats endpoint for subevents

* return ids of occupying objects instead of boolean flags

* wip

* include orderposition instead of order in seat info

* add API documentation

* Apply suggestions from code review

Co-authored-by: Raphael Michel <michel@rami.io>

* Apply suggestions from code review

* Clarify API docs

* add api examples

* add test cases

* require can_view_orders permission for retrieving seats

* improve permission handling

* Revert "improve permission handling"

This reverts commit f32b532cc6.

* improve permission handling (minimal version)

* formatting

* add permission tests

* fix bug

* update permission checks

* Apply suggestions from code review

Co-authored-by: Raphael Michel <michel@rami.io>

* add tests for permission checks

* add tests for expand=voucher and expand=cartposition

* remove unused parameter

* test query count

* codestyle

---------

Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
Mira
2024-08-02 09:17:46 +02:00
committed by GitHub
parent a0b046d204
commit dc1973f4ff
11 changed files with 548 additions and 19 deletions

View File

@@ -40,7 +40,9 @@ from django.utils.timezone import now
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import serializers, views, viewsets
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.exceptions import (
NotFound, PermissionDenied, ValidationError,
)
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
@@ -48,12 +50,12 @@ from pretix.api.auth.permission import EventCRUDPermission
from pretix.api.pagination import TotalOrderingFilter
from pretix.api.serializers.event import (
CloneEventSerializer, DeviceEventSettingsSerializer, EventSerializer,
EventSettingsSerializer, ItemMetaPropertiesSerializer, SubEventSerializer,
TaxRuleSerializer,
EventSettingsSerializer, ItemMetaPropertiesSerializer, SeatSerializer,
SubEventSerializer, TaxRuleSerializer,
)
from pretix.api.views import ConditionalListView
from pretix.base.models import (
CartPosition, Device, Event, ItemMetaProperty, SeatCategoryMapping,
CartPosition, Device, Event, ItemMetaProperty, Seat, SeatCategoryMapping,
TaxRule, TeamAPIToken,
)
from pretix.base.models.event import SubEvent
@@ -667,3 +669,44 @@ class EventSettingsView(views.APIView):
'request': request
})
return Response(s.data)
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',)
def get_queryset(self):
if self.request.event.has_subevents and 'subevent' in self.request.resolver_match.kwargs:
try:
subevent = self.request.event.subevents.get(pk=self.request.resolver_match.kwargs['subevent'])
except SubEvent.DoesNotExist:
raise NotFound('Subevent not found')
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:
qs = Seat.annotated(event_id=self.request.event.id, subevent=None, qs=self.request.event.seats.all(), annotate_ids=True)
else:
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,
}
return ctx
def perform_update(self, serializer):
super().perform_update(serializer)
serializer.instance.event.log_action(
"pretix.event.seats.blocks.changed",
user=self.request.user,
auth=self.request.auth,
data={"seats": [serializer.instance.pk]},
)