"""Tag views.""" from django.conf import settings from rest_framework import generics from rest_framework import mixins from rest_framework import permissions from rest_framework import status from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response from location.models import WineRegion from tag import filters from tag import models from tag import serializers class ChosenTagsView(generics.ListAPIView, viewsets.GenericViewSet): pagination_class = None permission_classes = (permissions.AllowAny,) serializer_class = serializers.TagBaseSerializer filterset_class = filters.TagsFilterSet queryset = models.Tag.objects.all() def get_queryset(self): result_tags_ids = models.ChosenTagSettings.objects \ .by_country_code(self.request.country_code) \ .values('tag_id') return models.Tag.objects \ .filter(id__in=result_tags_ids) \ .order_by_priority() def list(self, request, *args, **kwargs): # TMP TODO remove it later # Временный хардкод для демонстрации > 15 ноября, потом удалить! queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) result_list = serializer.data if request.query_params.get('type') and (settings.ESTABLISHMENT_CHOSEN_TAGS or settings.NEWS_CHOSEN_TAGS): ordered_list = settings.ESTABLISHMENT_CHOSEN_TAGS if request.query_params.get( 'type') == 'establishment' else settings.NEWS_CHOSEN_TAGS result_list = sorted(result_list, key=lambda x: ordered_list.index(x['index_name'])) return Response(result_list) # User`s views & viewsets class TagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ViewSet for TagCategory model.""" filterset_class = filters.TagCategoryFilterSet pagination_class = None permission_classes = (permissions.AllowAny,) queryset = models.TagCategory.objects.with_tags().with_base_related(). \ distinct() serializer_class = serializers.TagCategoryBaseSerializer # User`s views & viewsets class FiltersTagCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ViewSet for TagCategory model.""" filterset_class = filters.TagCategoryFilterSet pagination_class = None permission_classes = (permissions.AllowAny,) queryset = models.TagCategory.objects.with_tags().with_base_related(). \ distinct() serializer_class = serializers.FiltersTagCategoryBaseSerializer def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) serializer = self.get_serializer(queryset, many=True) result_list = serializer.data query_params = request.query_params params_type = query_params.get('type') week_days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") flags = ('toque_number', 'wine_region', 'works_noon', 'works_evening', 'works_now', 'works_at_weekday') filter_flags = {flag_name: False for flag_name in flags} additional_flags = [] if params_type == 'restaurant': additional_flags += ['toque_number', 'works_noon', 'works_evening', 'works_now'] elif params_type == 'winery': additional_flags += ['wine_region'] elif params_type == 'artisan': additional_flags += ['works_now', 'works_at_weekday'] for flag_name in additional_flags: filter_flags[flag_name] = True if filter_flags['toque_number']: toques = { "index_name": "toque_number", "label_translated": "Toques", "param_name": "toque_number__in", "filters": [{ "id": toque_id, "index_name": "toque_%d" % toque_id, "label_translated": "Toque %d" % toque_id } for toque_id in range(6)] } result_list.append(toques) if filter_flags['wine_region']: wine_region_id = query_params.get('wine_region_id__in') if str(wine_region_id).isdigit(): queryset = WineRegion.objects.filter(id=int(wine_region_id)) else: queryset = WineRegion.objects.all() wine_regions = { "index_name": "wine_region", "label_translated": "Wine region", "param_name": "wine_region_id__in", "filters": [{ "id": obj.id, "index_name": obj.name.lower().replace(' ', '_'), "label_translated": obj.name } for obj in queryset] } result_list.append(wine_regions) if filter_flags['works_noon']: works_noon = { "index_name": "works_noon", "label_translated": "Open noon", "param_name": "works_noon__in", "filters": [{ "id": weekday, "index_name": week_days[weekday].lower(), "label_translated": week_days[weekday] } for weekday in range(7)] } result_list.append(works_noon) if filter_flags['works_evening']: works_evening = { "index_name": "works_evening", "label_translated": "Open evening", "param_name": "works_evening__in", "filters": [{ "id": weekday, "index_name": week_days[weekday].lower(), "label_translated": week_days[weekday] } for weekday in range(7)] } result_list.append(works_evening) if filter_flags['works_now']: works_now = { "index_name": "open_now", "label_translated": "Open now", "param_name": "open_now", "type": True } result_list.append(works_now) if filter_flags['works_at_weekday']: works_at_weekday = { "index_name": "works_at_weekday", "label_translated": "Works at weekday", "param_name": "works_at_weekday__in", "filters": [{ "id": weekday, "index_name": week_days[weekday].lower(), "label_translated": week_days[weekday] } for weekday in range(7)] } result_list.append(works_at_weekday) if 'tags_id__in' in query_params: # filtering by params_type and tags id # todo: result_list.append( filtering_data ) pass return Response(result_list) # BackOffice user`s views & viewsets class BindObjectMixin: """Bind object mixin.""" def get_serializer_class(self): if self.action == 'bind_object': return self.bind_object_serializer_class return self.serializer_class def perform_binding(self, serializer): raise NotImplemented def perform_unbinding(self, serializer): raise NotImplemented @action(methods=['post', 'delete'], detail=True, url_path='bind-object') def bind_object(self, request, pk=None): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) if request.method == 'POST': self.perform_binding(serializer) return Response(serializer.data, status=status.HTTP_201_CREATED) elif request.method == 'DELETE': self.perform_unbinding(serializer) return Response(status=status.HTTP_204_NO_CONTENT) class TagBackOfficeViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, BindObjectMixin, viewsets.GenericViewSet): """List/create tag view.""" pagination_class = None permission_classes = (permissions.IsAuthenticated,) queryset = models.Tag.objects.all() serializer_class = serializers.TagBackOfficeSerializer bind_object_serializer_class = serializers.TagBindObjectSerializer def perform_binding(self, serializer): data = serializer.validated_data tag = data.pop('tag') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.ESTABLISHMENT: tag.establishments.add(related_object) elif obj_type == self.bind_object_serializer_class.NEWS: tag.news.add(related_object) def perform_unbinding(self, serializer): data = serializer.validated_data tag = data.pop('tag') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.ESTABLISHMENT: tag.establishments.remove(related_object) elif obj_type == self.bind_object_serializer_class.NEWS: tag.news.remove(related_object) class TagCategoryBackOfficeViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.RetrieveModelMixin, BindObjectMixin, TagCategoryViewSet): """ViewSet for TagCategory model for BackOffice users.""" permission_classes = (permissions.IsAuthenticated,) queryset = TagCategoryViewSet.queryset.with_extended_related() serializer_class = serializers.TagCategoryBackOfficeDetailSerializer bind_object_serializer_class = serializers.TagCategoryBindObjectSerializer def perform_binding(self, serializer): data = serializer.validated_data tag_category = data.pop('tag_category') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.ESTABLISHMENT_TYPE: tag_category.establishment_types.add(related_object) elif obj_type == self.bind_object_serializer_class.NEWS_TYPE: tag_category.news_types.add(related_object) def perform_unbinding(self, serializer): data = serializer.validated_data tag_category = data.pop('tag_category') obj_type = data.get('type') related_object = data.get('related_object') if obj_type == self.bind_object_serializer_class.ESTABLISHMENT_TYPE: tag_category.establishment_types.remove(related_object) elif obj_type == self.bind_object_serializer_class.NEWS_TYPE: tag_category.news_types.remove(related_object)