Quotas API: Allow to bulk-query availability

This commit is contained in:
Raphael Michel
2021-06-04 17:15:55 +02:00
parent 18df9d66bb
commit 9c3fc69176
3 changed files with 40 additions and 1 deletions

View File

@@ -28,12 +28,22 @@ closed boolean Whether the quo
field). field).
release_after_exit boolean Whether the quota regains capacity as soon as some tickets release_after_exit boolean Whether the quota regains capacity as soon as some tickets
have been scanned at an exit. have been scanned at an exit.
available boolean Whether this quota is available. Only returned if ``with_availability=true``
is set on the request. Do not rely on this value for critical operations, it may be
slightly out of date.
available_number integer Number of available tickets. Only returned if ``with_availability=true``
is set on the request. Do not rely on this value for critical operations, it may be
slightly out of date. ``null`` means unlimited.
===================================== ========================== ======================================================= ===================================== ========================== =======================================================
.. versionchanged:: 3.10 .. versionchanged:: 3.10
The attribute ``release_after_exit`` has been added. The attribute ``release_after_exit`` has been added.
.. versionchanged:: 4.1
The ``with_availability`` query parameter has been added.
Endpoints Endpoints
--------- ---------
@@ -80,6 +90,7 @@ Endpoints
:query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``. :query string ordering: Manually set the ordering of results. Valid fields to be used are ``id`` and ``position``.
Default: ``position`` Default: ``position``
:query integer subevent: Only return quotas of the sub-event with the given ID :query integer subevent: Only return quotas of the sub-event with the given ID
:query string with_availability: Set to ``true`` to get availability information. Can lead to increased answer times.
:param organizer: The ``slug`` field of the organizer to fetch :param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch :param event: The ``slug`` field of the event to fetch
:statuscode 200: no error :statuscode 200: no error
@@ -120,6 +131,7 @@ Endpoints
:param organizer: The ``slug`` field of the organizer to fetch :param organizer: The ``slug`` field of the organizer to fetch
:param event: The ``slug`` field of the event to fetch :param event: The ``slug`` field of the event to fetch
:param id: The ``id`` field of the quota to fetch :param id: The ``id`` field of the quota to fetch
:query string with_availability: Set to ``true`` to get availability information. Can lead to increased answer times.
:statuscode 200: no error :statuscode 200: no error
:statuscode 401: Authentication failure :statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource. :statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.

View File

@@ -408,10 +408,19 @@ class QuestionSerializer(I18nAwareModelSerializer):
class QuotaSerializer(I18nAwareModelSerializer): class QuotaSerializer(I18nAwareModelSerializer):
available = serializers.BooleanField(read_only=True)
available_number = serializers.IntegerField(read_only=True)
class Meta: class Meta:
model = Quota model = Quota
fields = ('id', 'name', 'size', 'items', 'variations', 'subevent', 'closed', 'close_when_sold_out', 'release_after_exit') fields = ('id', 'name', 'size', 'items', 'variations', 'subevent', 'closed', 'close_when_sold_out',
'release_after_exit', 'available', 'available_number')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'request' not in self.context or self.context['request'].GET.get('with_availability') != 'true':
del self.fields['available']
del self.fields['available_number']
def validate(self, data): def validate(self, data):
data = super().validate(data) data = super().validate(data)

View File

@@ -477,6 +477,23 @@ class QuotaViewSet(ConditionalListView, viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
return self.request.event.quotas.all() return self.request.event.quotas.all()
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if self.request.GET.get('with_availability') == 'true':
if page:
qa = QuotaAvailability()
qa.queue(*page)
qa.compute(allow_cache=False)
for q in page:
q.available = qa.results[q][0] == Quota.AVAILABILITY_OK
q.available_number = qa.results[q][1]
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(event=self.request.event) serializer.save(event=self.request.event)
serializer.instance.log_action( serializer.instance.log_action(
@@ -496,6 +513,7 @@ class QuotaViewSet(ConditionalListView, viewsets.ModelViewSet):
def get_serializer_context(self): def get_serializer_context(self):
ctx = super().get_serializer_context() ctx = super().get_serializer_context()
ctx['event'] = self.request.event ctx['event'] = self.request.event
ctx['request'] = self.request
return ctx return ctx
def perform_update(self, serializer): def perform_update(self, serializer):