from django.contrib.auth import get_user_model from django.db.models import Q from django.shortcuts import get_object_or_404 from django.utils.functional import cached_property from rest_framework.viewsets import ModelViewSet from rest_framework.filters import OrderingFilter from event.models import Activity, ActivityTag, ActivityTemplate, Event, Place from .serializers import ( ActivitySerializer, ActivityTagSerializer, ActivityTemplateSerializer, EventSerializer, PlaceSerializer, ) User = get_user_model() # classes utilitaires class EventUrlViewSetMixin: """ ViewSet mixin to handle the evenk_pk from url. """ @cached_property def event(self): event_pk = self.kwargs.get('event_pk') if event_pk: return get_object_or_404(Event, pk=event_pk) return None class EventModelViewSetMixin: def perform_create(self, serializer): serializer.save(event=self.event) def perform_update(self, serializer): serializer.save(event=self.event) class EventModelViewSet( EventModelViewSetMixin, EventUrlViewSetMixin, ModelViewSet, ): pass class EventSpecificModelViewSet(EventModelViewSet): """ ViewSet that returns : * rootlevel objects if no Event is specified * OR objects related to the specified event AND root level objects if an event is specified it passes the event_pk to the save method. Works fine with serializers.EventSpecificSerializer Useful for models that extends EventSpecificMixin """ def get_queryset(self): """ Warning : You may want to override this method and not call with super """ queryset = super().get_queryset() filters = Q(event=None) if self.event: filters |= Q(event=self.event) return queryset.filter(filters) # ViewSets class EventViewSet(ModelViewSet): queryset = Event.objects.all() serializer_class = EventSerializer filter_backends = (OrderingFilter,) ordering_fields = ('title', 'creation_date', 'beginning_date', 'ending_date', ) ordering = ('beginning_date', ) def perform_create(self, serializer): serializer.save(created_by=self.request.user) class PlaceViewSet(EventSpecificModelViewSet): queryset = Place.objects.all() serializer_class = PlaceSerializer filter_backends = (OrderingFilter,) ordering_fields = ('name', ) ordering = ('name', ) class ActivityTagViewSet(EventSpecificModelViewSet): queryset = ActivityTag.objects.all() serializer_class = ActivityTagSerializer filter_backends = (OrderingFilter,) ordering_fields = ('is_public', 'name', ) ordering = ('is_public', 'name', ) class ActivityTemplateViewSet(EventModelViewSet): queryset = ActivityTemplate.objects.all() serializer_class = ActivityTemplateSerializer filter_backends = (OrderingFilter,) ordering_fields = ('title', ) ordering = ('title', ) class ActivityViewSet(EventModelViewSet): queryset = Activity.objects.all() serializer_class = ActivitySerializer filter_backends = (OrderingFilter,) ordering_fields = ('title', ) ordering = ('title', )