From 0851a9e6d68a29ff55484855c353a952053ca379 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Wed, 18 Dec 2019 15:19:04 +0300 Subject: [PATCH] added filter values in guide views --- apps/collection/models.py | 81 ++++++++++++++++++++++++++- apps/collection/serializers/common.py | 23 ++++++++ apps/collection/urls/back.py | 2 + apps/collection/views/back.py | 10 ++-- 4 files changed, 109 insertions(+), 7 deletions(-) diff --git a/apps/collection/models.py b/apps/collection/models.py index 90837cd7..b3dd44ef 100644 --- a/apps/collection/models.py +++ b/apps/collection/models.py @@ -1,17 +1,21 @@ import re -from mptt.models import MPTTModel, TreeForeignKey + from django.contrib.contenttypes.fields import ContentType from django.contrib.postgres.fields import JSONField from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.utils.translation import gettext_lazy as _ +from mptt.models import MPTTModel, TreeForeignKey +from location.models import Country, Region, WineRegion, WineSubRegion +from translation.models import Language +from review.models import Review +from utils.models import IntermediateGalleryModelMixin, GalleryModelMixin from utils.models import ( ProjectBaseMixin, TJSONField, TranslatedFieldsMixin, URLImageMixin, ) from utils.querysets import RelatedObjectsCountMixin -from utils.models import IntermediateGalleryModelMixin, GalleryModelMixin # Mixins @@ -166,6 +170,14 @@ class GuideType(ProjectBaseMixin): class GuideQuerySet(models.QuerySet): """QuerySet for Guide.""" + def with_base_related(self): + """Return QuerySet with related.""" + return self.select_related('guide_type', 'site') + + def by_country_id(self, country_id): + """Return QuerySet filtered by country code.""" + return self.filter(country_json__id__contains=country_id) + class Guide(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin): """Guide model.""" @@ -289,6 +301,71 @@ class GuideFilter(ProjectBaseMixin): verbose_name = _('guide filter') verbose_name_plural = _('guide filters') + def get_value_list(self, json_field: dict, + model: object, + lookup_field: str, + search_field: int = 'id') -> list: + """ + Function to return an array with correct values from ids. + Algorithm: + 1 Get values from json_field + 2 Try to find model instances by search field and value from json field + 3 If instance was found, then put value into array from instance by lookup field + """ + + value_list = [] + if hasattr(model, 'objects'): + for value in getattr(json_field, 'get')(search_field): + qs = model.objects.filter(**{search_field: value}) + if qs.exists(): + value_list.append(getattr(qs.first(), lookup_field)) + return value_list + + @property + def establishment_types(self): + from establishment.models import EstablishmentType + return self.get_value_list(json_field=self.establishment_type_json, + model=EstablishmentType, + lookup_field='index_name') + + @property + def locales(self): + return self.get_value_list(json_field=self.locale_json, + model=Language, + lookup_field='locale') + + @property + def review_states(self): + states = [] + for state in self.review_state_json.get('state'): + status_field = [field for field in Review._meta.fields + if field.name == 'status'][0] + status_field_id = Review._meta.fields.index(status_field) + states.append(dict(Review._meta.fields[status_field_id].choices).get(state)) + return states + + @property + def country_names(self): + return self.get_value_list(json_field=self.country_json, + model=Country, + lookup_field='name_translated') + + @property + def region_names(self): + return self.get_value_list(json_field=self.region_json, + model=Region, + lookup_field='name') + + @property + def sub_region_names(self): + return self.get_value_list(json_field=self.region_json, + model=Country, + lookup_field='name_translated') + + @property + def review_vintages(self): + return self.review_vintage_json.get('vintage') + class GuideElementType(models.Model): """Model for type of guide elements.""" diff --git a/apps/collection/serializers/common.py b/apps/collection/serializers/common.py index 59ac5065..8b8a3566 100644 --- a/apps/collection/serializers/common.py +++ b/apps/collection/serializers/common.py @@ -60,6 +60,26 @@ class GuideTypeBaseSerializer(serializers.ModelSerializer): ] +class GuideFilterBaseSerialzer(serializers.ModelSerializer): + """Serializer for model GuideFilter.""" + + class Meta: + """Meta class.""" + model = models.GuideFilter + fields = [ + 'establishment_types', + 'locales', + 'review_states', + 'country_names', + 'region_names', + 'sub_region_names', + 'review_vintages', + 'max_mark', + 'min_mark', + 'with_mark', + ] + + class GuideBaseSerializer(serializers.ModelSerializer): """Guide serializer""" state_display = serializers.CharField(source='get_state_display', @@ -69,6 +89,8 @@ class GuideBaseSerializer(serializers.ModelSerializer): site_detail = SiteShortSerializer(read_only=True, source='site') entities = serializers.DictField(read_only=True) + guide_filters = GuideFilterBaseSerialzer(read_only=True, + source='guidefilter') class Meta: model = models.Guide @@ -86,6 +108,7 @@ class GuideBaseSerializer(serializers.ModelSerializer): 'state', 'state_display', 'entities', + 'guide_filters', ] extra_kwargs = { 'guide_type': {'write_only': True}, diff --git a/apps/collection/urls/back.py b/apps/collection/urls/back.py index 6db5bde2..f2297e2e 100644 --- a/apps/collection/urls/back.py +++ b/apps/collection/urls/back.py @@ -12,6 +12,8 @@ router.register(r'collections', views.CollectionBackOfficeViewSet) urlpatterns = [ path('guides/', views.GuideListCreateView.as_view(), name='guide-list-create'), + # path('guides//elements/', views.GuideElementListView.as_view(), + # name='guide-element-list'), path('guides//filters/', views.GuideFilterCreateView.as_view(), name='guide-filter-list-create'), ] + router.urls diff --git a/apps/collection/views/back.py b/apps/collection/views/back.py index b1f25628..278e1691 100644 --- a/apps/collection/views/back.py +++ b/apps/collection/views/back.py @@ -7,6 +7,7 @@ from rest_framework.response import Response from collection import models, serializers from utils.views import BindObjectMixin +from django.db.models import Prefetch class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): @@ -26,10 +27,9 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): class GuideBaseView(generics.GenericAPIView): """ViewSet for Guide model.""" - pagination_class = None - queryset = models.Guide.objects.all() + queryset = models.Guide.objects.with_base_related() serializer_class = serializers.GuideBaseSerializer - permission_classes = (permissions.IsAuthenticated,) + permission_classes = (permissions.IsAuthenticated, ) class GuideFilterBaseView(generics.GenericAPIView): @@ -80,7 +80,7 @@ class CollectionBackOfficeViewSet(mixins.CreateModelMixin, class GuideListCreateView(GuideBaseView, generics.ListCreateAPIView): - """ViewSet for Guide model for BackOffice users.""" + """View for Guide model for BackOffice users.""" def post(self, request, *args, **kwargs): super().create(request, *args, **kwargs) return Response(status=status.HTTP_200_OK) @@ -88,7 +88,7 @@ class GuideListCreateView(GuideBaseView, class GuideFilterCreateView(GuideFilterBaseView, generics.CreateAPIView): - """ViewSet for GuideFilter model for BackOffice users.""" + """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)