api: move serializers to new file (#56083)
This commit is contained in:
parent
9d90cb6618
commit
95e2618863
|
@ -0,0 +1,93 @@
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from chrono.agendas.models import Booking
|
||||
|
||||
|
||||
class StringOrListField(serializers.ListField):
|
||||
def to_internal_value(self, data):
|
||||
if isinstance(data, str):
|
||||
data = [s.strip() for s in data.split(',') if s.strip()]
|
||||
return super().to_internal_value(data)
|
||||
|
||||
|
||||
class SlotSerializer(serializers.Serializer):
|
||||
label = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_external_id = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_name = serializers.CharField(max_length=250, allow_blank=True) # compatibility
|
||||
user_first_name = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_last_name = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_display_label = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_email = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_phone_number = serializers.CharField(max_length=16, allow_blank=True)
|
||||
exclude_user = serializers.BooleanField(default=False)
|
||||
events = serializers.CharField(max_length=16, allow_blank=True)
|
||||
form_url = serializers.CharField(max_length=250, allow_blank=True)
|
||||
backoffice_url = serializers.URLField(allow_blank=True)
|
||||
cancel_callback_url = serializers.URLField(allow_blank=True)
|
||||
count = serializers.IntegerField(min_value=1)
|
||||
cancel_booking_id = serializers.CharField(max_length=250, allow_blank=True, allow_null=True)
|
||||
force_waiting_list = serializers.BooleanField(default=False)
|
||||
use_color_for = serializers.CharField(max_length=250, allow_blank=True)
|
||||
|
||||
|
||||
class SlotsSerializer(SlotSerializer):
|
||||
slots = StringOrListField(required=True, child=serializers.CharField(max_length=160, allow_blank=False))
|
||||
|
||||
def validate(self, attrs):
|
||||
super().validate(attrs)
|
||||
if not attrs.get('slots'):
|
||||
raise serializers.ValidationError({'slots': _('This field is required.')})
|
||||
return attrs
|
||||
|
||||
|
||||
class EventsSlotsSerializer(SlotSerializer):
|
||||
slots = StringOrListField(required=True, child=serializers.CharField(max_length=160))
|
||||
|
||||
def validate(self, attrs):
|
||||
super().validate(attrs)
|
||||
if not 'slots' in attrs:
|
||||
raise serializers.ValidationError({'slots': _('This field is required.')})
|
||||
if not attrs.get('user_external_id'):
|
||||
raise serializers.ValidationError({'user_external_id': _('This field is required.')})
|
||||
return attrs
|
||||
|
||||
|
||||
class BookingSerializer(serializers.ModelSerializer):
|
||||
user_absence_reason = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = Booking
|
||||
fields = ['id', 'in_waiting_list', 'user_was_present', 'user_absence_reason', 'extra_data']
|
||||
read_only_fields = ['id', 'in_waiting_list']
|
||||
|
||||
def validate_user_absence_reason(self, value):
|
||||
if not value:
|
||||
return ''
|
||||
|
||||
if not self.instance.event.agenda.absence_reasons_group:
|
||||
raise serializers.ValidationError(_('unknown absence reason'))
|
||||
|
||||
reasons_qs = self.instance.event.agenda.absence_reasons_group.absence_reasons
|
||||
try:
|
||||
reason = reasons_qs.get(slug=value)
|
||||
value = reason.label
|
||||
except AbsenceReason.DoesNotExist:
|
||||
if not reasons_qs.filter(label=value).exists():
|
||||
raise serializers.ValidationError(_('unknown absence reason'))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class ResizeSerializer(serializers.Serializer):
|
||||
count = serializers.IntegerField(min_value=1)
|
||||
|
||||
|
||||
class StatisticsFiltersSerializer(serializers.Serializer):
|
||||
time_interval = serializers.ChoiceField(choices=('day', _('Day')), default='day')
|
||||
start = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
||||
end = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
||||
category = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
||||
agenda = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
||||
group_by = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
|
@ -35,7 +35,7 @@ from django.utils.timezone import is_naive, localtime, make_aware, now
|
|||
from django.utils.translation import gettext_noop
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django_filters import rest_framework as filters
|
||||
from rest_framework import permissions, serializers, status
|
||||
from rest_framework import permissions, status
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.generics import ListAPIView
|
||||
from rest_framework.views import APIView
|
||||
|
@ -51,6 +51,7 @@ from chrono.agendas.models import (
|
|||
MeetingType,
|
||||
TimePeriodException,
|
||||
)
|
||||
from chrono.api import serializers
|
||||
from chrono.api.utils import APIError, Response
|
||||
from chrono.interval import IntervalSet
|
||||
|
||||
|
@ -1117,67 +1118,9 @@ class AgendaResourceList(APIView):
|
|||
agenda_resource_list = AgendaResourceList.as_view()
|
||||
|
||||
|
||||
class SlotSerializer(serializers.Serializer):
|
||||
"""
|
||||
payload to fill one slot. The slot (event id) is in the URL.
|
||||
"""
|
||||
|
||||
label = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_external_id = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_name = serializers.CharField(max_length=250, allow_blank=True) # compatibility
|
||||
user_first_name = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_last_name = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_display_label = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_email = serializers.CharField(max_length=250, allow_blank=True)
|
||||
user_phone_number = serializers.CharField(max_length=16, allow_blank=True)
|
||||
exclude_user = serializers.BooleanField(default=False)
|
||||
events = serializers.CharField(max_length=16, allow_blank=True)
|
||||
form_url = serializers.CharField(max_length=250, allow_blank=True)
|
||||
backoffice_url = serializers.URLField(allow_blank=True)
|
||||
cancel_callback_url = serializers.URLField(allow_blank=True)
|
||||
count = serializers.IntegerField(min_value=1)
|
||||
cancel_booking_id = serializers.CharField(max_length=250, allow_blank=True, allow_null=True)
|
||||
force_waiting_list = serializers.BooleanField(default=False)
|
||||
use_color_for = serializers.CharField(max_length=250, allow_blank=True)
|
||||
|
||||
|
||||
class StringOrListField(serializers.ListField):
|
||||
def to_internal_value(self, data):
|
||||
if isinstance(data, str):
|
||||
data = [s.strip() for s in data.split(',') if s.strip()]
|
||||
return super().to_internal_value(data)
|
||||
|
||||
|
||||
class SlotsSerializer(SlotSerializer):
|
||||
"""
|
||||
payload to fill multiple slots: same as SlotSerializer, but the
|
||||
slots list is in the payload.
|
||||
"""
|
||||
|
||||
slots = StringOrListField(required=True, child=serializers.CharField(max_length=160, allow_blank=False))
|
||||
|
||||
def validate(self, attrs):
|
||||
super().validate(attrs)
|
||||
if not attrs.get('slots'):
|
||||
raise serializers.ValidationError({'slots': _('This field is required.')})
|
||||
return attrs
|
||||
|
||||
|
||||
class EventsSlotsSerializer(SlotSerializer):
|
||||
slots = StringOrListField(required=True, child=serializers.CharField(max_length=160))
|
||||
|
||||
def validate(self, attrs):
|
||||
super().validate(attrs)
|
||||
if not 'slots' in attrs:
|
||||
raise serializers.ValidationError({'slots': _('This field is required.')})
|
||||
if not attrs.get('user_external_id'):
|
||||
raise serializers.ValidationError({'user_external_id': _('This field is required.')})
|
||||
return attrs
|
||||
|
||||
|
||||
class Fillslots(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = SlotsSerializer
|
||||
serializer_class = serializers.SlotsSerializer
|
||||
|
||||
def post(self, request, agenda_identifier=None, event_identifier=None, format=None):
|
||||
return self.fillslot(request=request, agenda_identifier=agenda_identifier, format=format)
|
||||
|
@ -1539,7 +1482,7 @@ fillslots = Fillslots.as_view()
|
|||
|
||||
|
||||
class Fillslot(Fillslots):
|
||||
serializer_class = SlotSerializer
|
||||
serializer_class = serializers.SlotSerializer
|
||||
|
||||
def post(self, request, agenda_identifier=None, event_identifier=None, format=None):
|
||||
return self.fillslot(
|
||||
|
@ -1555,7 +1498,7 @@ fillslot = Fillslot.as_view()
|
|||
|
||||
class RecurringFillslots(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = EventsSlotsSerializer
|
||||
serializer_class = serializers.EventsSlotsSerializer
|
||||
|
||||
def post(self, request, agenda_identifier):
|
||||
if not settings.ENABLE_RECURRING_EVENT_BOOKING:
|
||||
|
@ -1657,7 +1600,7 @@ recurring_fillslots = RecurringFillslots.as_view()
|
|||
|
||||
class EventsFillslots(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = EventsSlotsSerializer
|
||||
serializer_class = serializers.EventsSlotsSerializer
|
||||
|
||||
def post(self, request, agenda_identifier):
|
||||
agenda = get_object_or_404(Agenda, slug=agenda_identifier, kind='events')
|
||||
|
@ -1729,32 +1672,6 @@ class EventsFillslots(APIView):
|
|||
events_fillslots = EventsFillslots.as_view()
|
||||
|
||||
|
||||
class BookingSerializer(serializers.ModelSerializer):
|
||||
user_absence_reason = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = Booking
|
||||
fields = ['id', 'in_waiting_list', 'user_was_present', 'user_absence_reason', 'extra_data']
|
||||
read_only_fields = ['id', 'in_waiting_list']
|
||||
|
||||
def validate_user_absence_reason(self, value):
|
||||
if not value:
|
||||
return ''
|
||||
|
||||
if not self.instance.event.agenda.absence_reasons_group:
|
||||
raise serializers.ValidationError(_('unknown absence reason'))
|
||||
|
||||
reasons_qs = self.instance.event.agenda.absence_reasons_group.absence_reasons
|
||||
try:
|
||||
reason = reasons_qs.get(slug=value)
|
||||
value = reason.label
|
||||
except AbsenceReason.DoesNotExist:
|
||||
if not reasons_qs.filter(label=value).exists():
|
||||
raise serializers.ValidationError(_('unknown absence reason'))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class BookingFilter(filters.FilterSet):
|
||||
agenda = filters.CharFilter(field_name='event__agenda__slug', lookup_expr='exact')
|
||||
category = filters.CharFilter(field_name='event__agenda__category__slug', lookup_expr='exact')
|
||||
|
@ -1781,7 +1698,7 @@ class BookingFilter(filters.FilterSet):
|
|||
|
||||
class BookingsAPI(ListAPIView):
|
||||
filter_backends = (filters.DjangoFilterBackend,)
|
||||
serializer_class = BookingSerializer
|
||||
serializer_class = serializers.BookingSerializer
|
||||
filterset_class = BookingFilter
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
@ -1817,7 +1734,7 @@ bookings = BookingsAPI.as_view()
|
|||
|
||||
class BookingAPI(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = BookingSerializer
|
||||
serializer_class = serializers.BookingSerializer
|
||||
|
||||
def initial(self, request, *args, **kwargs):
|
||||
super().initial(request, *args, **kwargs)
|
||||
|
@ -2055,10 +1972,6 @@ class AnonymizeBooking(APIView):
|
|||
anonymize_booking = AnonymizeBooking.as_view()
|
||||
|
||||
|
||||
class ResizeSerializer(serializers.Serializer):
|
||||
count = serializers.IntegerField(min_value=1)
|
||||
|
||||
|
||||
class ResizeBooking(APIView):
|
||||
"""
|
||||
Resize a booking.
|
||||
|
@ -2070,7 +1983,7 @@ class ResizeBooking(APIView):
|
|||
"""
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = ResizeSerializer
|
||||
serializer_class = serializers.ResizeSerializer
|
||||
|
||||
def post(self, request, booking_pk=None, format=None):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
|
@ -2361,20 +2274,12 @@ class StatisticsList(APIView):
|
|||
statistics_list = StatisticsList.as_view()
|
||||
|
||||
|
||||
class StatisticsFiltersSerializer(serializers.Serializer):
|
||||
time_interval = serializers.ChoiceField(choices=('day', _('Day')), default='day')
|
||||
start = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
||||
end = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
||||
category = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
||||
agenda = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
||||
group_by = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
||||
|
||||
|
||||
class BookingsStatistics(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = serializers.StatisticsFiltersSerializer
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
serializer = StatisticsFiltersSerializer(data=request.query_params)
|
||||
serializer = self.serializer_class(data=request.query_params)
|
||||
if not serializer.is_valid():
|
||||
raise APIError(
|
||||
_('invalid statistics filters'),
|
||||
|
|
Loading…
Reference in New Issue