from django.shortcuts import get_object_or_404 from django.utils.translation import gettext_lazy as _ from rest_framework import generics, mixins, permissions, status, viewsets from rest_framework.response import Response from collection import filters, models, serializers, tasks from utils.methods import get_permission_classes from utils.views import BindObjectMixin class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ViewSet for Collection model.""" # pagination_class = None serializer_class = serializers.CollectionBackOfficeSerializer permission_classes = (permissions.AllowAny,) def get_queryset(self): """Overridden method 'get_queryset'.""" qs = models.Collection.objects.all().order_by('-created').with_base_related() if self.request.country_code: qs = qs.by_country_code(self.request.country_code) return qs class GuideBaseView(generics.GenericAPIView): """ViewSet for Guide model.""" serializer_class = serializers.GuideBaseSerializer permission_classes = get_permission_classes() def get_queryset(self): """An overridden get_queryset method.""" queryset = models.Guide.objects.with_base_related if hasattr(self.request, 'country_code'): return queryset().by_country_code(self.request.country_code).order_by('-created') return queryset().none() class GuideFilterBaseView(generics.GenericAPIView): """ViewSet for GuideFilter model.""" pagination_class = None queryset = models.GuideFilter.objects.all() serializer_class = serializers.GuideFilterBaseSerializer permission_classes = get_permission_classes() class GuideElementBaseView(generics.GenericAPIView): """Base view for GuideElement model.""" pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer permission_classes = get_permission_classes() class AdvertorialBaseView(generics.GenericAPIView): """Base view for Advertorial model.""" pagination_class = None queryset = models.Advertorial.objects.all() serializer_class = serializers.AdvertorialBaseSerializer permission_classes = get_permission_classes() class CollectionBackOfficeViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.RetrieveModelMixin, BindObjectMixin, CollectionViewSet): """ViewSet for Collections list for BackOffice users and Collection create.""" queryset = models.Collection.objects.with_base_related().order_by('-created') filter_class = filters.CollectionFilterSet serializer_class = serializers.CollectionBackOfficeSerializer bind_object_serializer_class = serializers.CollectionBindObjectSerializer permission_classes = (permissions.AllowAny, ) def perform_binding(self, serializer): data = serializer.validated_data collection = data.pop('collection') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.ESTABLISHMENT: collection.establishments.add(related_object) elif obj_type == self.bind_object_serializer_class.PRODUCT: collection.products.add(related_object) def perform_unbinding(self, serializer): data = serializer.validated_data collection = data.pop('collection') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.ESTABLISHMENT: collection.establishments.remove(related_object) elif obj_type == self.bind_object_serializer_class.PRODUCT: collection.products.remove(related_object) class CollectionBackOfficeList(CollectionBackOfficeViewSet): """ViewSet for Collections list for BackOffice users and Collection create.""" pagination_class = None class GuideListCreateView(GuideBaseView, generics.ListCreateAPIView): """ ## Guide list/create view. ### Request For creating new instance of Guide model, need to pass the following data in the request: required fields: * name (str) - guide name * start (str) - guide start datetime (datetime in a format `ISO-8601`) * vintage (str) - valid year * guide_type (int) - guide type enum: `0 (Restaurant), 1 (Artisan), 2 (Wine)` * site (int) - identifier of site non-required fields: * slug - generated automatically if not provided * state - state enum`: `0 (Built), 1 (Waiting), 2 (Removing), 3 (Building)` (service states) * end - guide end date (datetime in a format `ISO-8601`) ### Response Return paginated list of guides. E.g.: ``` { "count": 58, "next": 2, "previous": null, "results": [ { "id": 1, ... } ] } ``` ### Description *GET* Return paginated list of guides with the opportunity of filtering by next fields: * establishment_id (int) - identifier of establishment, * guide_type (int) - guide type enum: `0 (Restaurant), 1 (Artisan), 2 (Wine)` *POST* Create a new instance of guide. """ filter_class = filters.GuideFilterSet def create(self, request, *args, **kwargs): """Overridden create method.""" super(GuideListCreateView, self).create(request, *args, **kwargs) return Response(status=status.HTTP_201_CREATED) class GuideListView(generics.ListAPIView): """View for Guides list.""" pagination_class = None serializer_class = serializers.GuideShortSerializer filter_class = filters.GuideFilterSet def get_queryset(self): """An overridden get_queryset method.""" if hasattr(self.request, 'country_code'): return ( models.Guide.objects.by_country_code(self.request.country_code) .order_by('-created') ) return models.Guide.objects.none() class GuideBackOfficeList(BindObjectMixin, GuideBaseView): """ViewSet for Guides list for BackOffice users""" pagination_class = None filter_class = filters.GuideFilterSet bind_object_serializer_class = serializers.GuideBindObjectSerializer def perform_binding(self, serializer): data = serializer.validated_data guide = data.pop('guide') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.GUIDE: guide.establishments.add(related_object) elif obj_type == self.bind_object_serializer_class.PRODUCT: guide.products.add(related_object) def perform_unbinding(self, serializer): data = serializer.validated_data guide = data.pop('guide') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.GUIDE: guide.establishments.remove(related_object) elif obj_type == self.bind_object_serializer_class.PRODUCT: guide.products.remove(related_object) class GuideFilterCreateView(GuideFilterBaseView, generics.CreateAPIView): """View for GuideFilter model for BackOffice users.""" def post(self, request, *args, **kwargs): super().create(request, *args, **kwargs) return Response(status=status.HTTP_200_OK) class GuideElementListView(GuideElementBaseView, generics.ListAPIView): """View for model GuideElement for back office users.""" def get_queryset(self): """Overridden get_queryset method.""" guide = get_object_or_404(models.Guide.objects.all(), pk=self.kwargs.get('pk')) node = models.GuideElement.objects.get_root_node(guide) if node: return node.get_children() else: return models.GuideElement.objects.none() class GuideUpdateView(GuideBaseView): """View for model GuideElement for back office users.""" def get(self, request, *args, **kwargs): """POST-method to regenerate elements of guide instance.""" guide = get_object_or_404(models.Guide.objects.all(), pk=self.kwargs.get('pk')) guide.regenerate_elements() return Response(status=status.HTTP_200_OK) class AdvertorialCreateView(AdvertorialBaseView, generics.CreateAPIView): """View for model Advertorial for back office users.""" def post(self, request, *args, **kwargs): """Overridden post method.""" super(AdvertorialCreateView, self).create(request, *args, **kwargs) return Response(status=status.HTTP_200_OK) class AdvertorialDestroyView(AdvertorialBaseView, generics.DestroyAPIView): """View for model Advertorial for back office users.""" lookup_url_kwarg = 'advertorial_pk' def delete(self, request, *args, **kwargs): """Overridden delete method.""" return self.destroy(request, *args, **kwargs) class GuideElementExportCSVView(generics.ListAPIView): """Guide element export csv view.""" pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly,) def get(self, request, *args, **kwargs): """Overridden get_queryset method.""" guide = get_object_or_404( models.Guide.objects.all(), pk=self.kwargs.get('pk')) tasks.export_guide(guide_id=guide.id, user_id=request.user.id) return Response({"success": _('The file will be sent to your email.')}, status=status.HTTP_200_OK) class GuideElementExportXMLView(generics.ListAPIView): """Guide element export xml view.""" pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer permission_classes = get_permission_classes() def get(self, request, *args, **kwargs): """Overridden get_queryset method.""" guide = get_object_or_404( models.Guide.objects.all(), pk=self.kwargs.get('pk')) tasks.export_guide(guide_id=guide.id, user_id=request.user.id, file_type='xml') return Response({"success": _('The file will be sent to your email.')}, status=status.HTTP_200_OK) class GuideElementExportDOCView(generics.ListAPIView): """Guide element export doc view.""" pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer permission_classes = get_permission_classes() def get(self, request, *args, **kwargs): """Overridden get_queryset method.""" guide = get_object_or_404( models.Guide.objects.all(), pk=self.kwargs.get('pk')) guide.export_to_file(user_id=request.user.id, file_type='doc') return Response({"success": _('The file will be sent to your email.')}, status=status.HTTP_200_OK)