added filter values in guide views

This commit is contained in:
Anatoly 2019-12-18 15:19:04 +03:00
parent 2401763e6c
commit 0851a9e6d6
4 changed files with 109 additions and 7 deletions

View File

@ -1,17 +1,21 @@
import re import re
from mptt.models import MPTTModel, TreeForeignKey
from django.contrib.contenttypes.fields import ContentType from django.contrib.contenttypes.fields import ContentType
from django.contrib.postgres.fields import JSONField from django.contrib.postgres.fields import JSONField
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ 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 ( from utils.models import (
ProjectBaseMixin, TJSONField, TranslatedFieldsMixin, ProjectBaseMixin, TJSONField, TranslatedFieldsMixin,
URLImageMixin, URLImageMixin,
) )
from utils.querysets import RelatedObjectsCountMixin from utils.querysets import RelatedObjectsCountMixin
from utils.models import IntermediateGalleryModelMixin, GalleryModelMixin
# Mixins # Mixins
@ -166,6 +170,14 @@ class GuideType(ProjectBaseMixin):
class GuideQuerySet(models.QuerySet): class GuideQuerySet(models.QuerySet):
"""QuerySet for Guide.""" """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): class Guide(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
"""Guide model.""" """Guide model."""
@ -289,6 +301,71 @@ class GuideFilter(ProjectBaseMixin):
verbose_name = _('guide filter') verbose_name = _('guide filter')
verbose_name_plural = _('guide filters') 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): class GuideElementType(models.Model):
"""Model for type of guide elements.""" """Model for type of guide elements."""

View File

@ -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): class GuideBaseSerializer(serializers.ModelSerializer):
"""Guide serializer""" """Guide serializer"""
state_display = serializers.CharField(source='get_state_display', state_display = serializers.CharField(source='get_state_display',
@ -69,6 +89,8 @@ class GuideBaseSerializer(serializers.ModelSerializer):
site_detail = SiteShortSerializer(read_only=True, site_detail = SiteShortSerializer(read_only=True,
source='site') source='site')
entities = serializers.DictField(read_only=True) entities = serializers.DictField(read_only=True)
guide_filters = GuideFilterBaseSerialzer(read_only=True,
source='guidefilter')
class Meta: class Meta:
model = models.Guide model = models.Guide
@ -86,6 +108,7 @@ class GuideBaseSerializer(serializers.ModelSerializer):
'state', 'state',
'state_display', 'state_display',
'entities', 'entities',
'guide_filters',
] ]
extra_kwargs = { extra_kwargs = {
'guide_type': {'write_only': True}, 'guide_type': {'write_only': True},

View File

@ -12,6 +12,8 @@ router.register(r'collections', views.CollectionBackOfficeViewSet)
urlpatterns = [ urlpatterns = [
path('guides/', views.GuideListCreateView.as_view(), path('guides/', views.GuideListCreateView.as_view(),
name='guide-list-create'), name='guide-list-create'),
# path('guides/<int:pk>/elements/', views.GuideElementListView.as_view(),
# name='guide-element-list'),
path('guides/<int:pk>/filters/', views.GuideFilterCreateView.as_view(), path('guides/<int:pk>/filters/', views.GuideFilterCreateView.as_view(),
name='guide-filter-list-create'), name='guide-filter-list-create'),
] + router.urls ] + router.urls

View File

@ -7,6 +7,7 @@ from rest_framework.response import Response
from collection import models, serializers from collection import models, serializers
from utils.views import BindObjectMixin from utils.views import BindObjectMixin
from django.db.models import Prefetch
class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
@ -26,10 +27,9 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
class GuideBaseView(generics.GenericAPIView): class GuideBaseView(generics.GenericAPIView):
"""ViewSet for Guide model.""" """ViewSet for Guide model."""
pagination_class = None queryset = models.Guide.objects.with_base_related()
queryset = models.Guide.objects.all()
serializer_class = serializers.GuideBaseSerializer serializer_class = serializers.GuideBaseSerializer
permission_classes = (permissions.IsAuthenticated,) permission_classes = (permissions.IsAuthenticated, )
class GuideFilterBaseView(generics.GenericAPIView): class GuideFilterBaseView(generics.GenericAPIView):
@ -80,7 +80,7 @@ class CollectionBackOfficeViewSet(mixins.CreateModelMixin,
class GuideListCreateView(GuideBaseView, class GuideListCreateView(GuideBaseView,
generics.ListCreateAPIView): generics.ListCreateAPIView):
"""ViewSet for Guide model for BackOffice users.""" """View for Guide model for BackOffice users."""
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
super().create(request, *args, **kwargs) super().create(request, *args, **kwargs)
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@ -88,7 +88,7 @@ class GuideListCreateView(GuideBaseView,
class GuideFilterCreateView(GuideFilterBaseView, class GuideFilterCreateView(GuideFilterBaseView,
generics.CreateAPIView): generics.CreateAPIView):
"""ViewSet for GuideFilter model for BackOffice users.""" """View for GuideFilter model for BackOffice users."""
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
super().create(request, *args, **kwargs) super().create(request, *args, **kwargs)
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)