intermediate commit

This commit is contained in:
Anatoly 2019-12-23 12:38:13 +03:00
parent f87d891daa
commit 7452f0bef0
11 changed files with 123 additions and 15 deletions

View File

@ -568,6 +568,10 @@ class GuideElementQuerySet(models.QuerySet):
"""Return GuideElement with type WineNode."""
return self.filter(guide_element_type__name='WineNode')
def descendants(self):
"""Return QuerySet with descendants."""
return self.exclude(guide_element_type__name='Root')
class GuideElement(ProjectBaseMixin, MPTTModel):
"""Frozen state of elements of guide instance."""

View File

@ -4,6 +4,9 @@ from collection import models
from location import models as location_models
from main.serializers import SiteShortSerializer
from utils.serializers import TranslatedField
from rest_framework_recursive.fields import RecursiveField
from establishment.serializers import EstablishmentGuideElementSerializer
from product.serializers import ProductGuideElementSerializer
class CollectionBaseSerializer(serializers.ModelSerializer):
@ -94,7 +97,8 @@ class GuideBaseSerializer(serializers.ModelSerializer):
restaurant_counter = serializers.IntegerField(read_only=True)
shop_counter = serializers.IntegerField(read_only=True)
wine_counter = serializers.IntegerField(read_only=True)
present_objects_counter = serializers.IntegerField(read_only=True)
count_objects_during_init = serializers.IntegerField(read_only=True,
source='count_related_objects')
class Meta:
model = models.Guide
@ -115,7 +119,6 @@ class GuideBaseSerializer(serializers.ModelSerializer):
'restaurant_counter',
'shop_counter',
'wine_counter',
'present_objects_counter',
'count_objects_during_init',
]
extra_kwargs = {
@ -166,3 +169,36 @@ class GuideFilterBaseSerializer(serializers.ModelSerializer):
"""Overridden create method."""
validated_data['guide'] = self.get_guide(validated_data.pop('guide', None))
return super().create(validated_data)
class GuideElementBaseSerializer(serializers.ModelSerializer):
"""Serializer for model GuideElement."""
establishment_detail = EstablishmentGuideElementSerializer(read_only=True,
source='establishment')
section_name = serializers.CharField(source='section.name',
allow_null=True)
wine_color_section_name = serializers.CharField(source='wine_color_section.name',
allow_null=True)
node_name = serializers.CharField(source='guide_element_type.name')
label_photo = serializers.ImageField(source='label_photo.image', allow_null=True)
city_name = serializers.CharField(source='city.name', allow_null=True)
product_detail = ProductGuideElementSerializer(read_only=True, source='product')
parent = RecursiveField(required=False)
class Meta:
"""Meta class."""
model = models.GuideElement
fields = [
'node_name',
'establishment_detail',
'review',
'wine_region',
'product_detail',
'priority',
'city_name',
'section_name',
'wine_color_section_name',
'parent',
'label_photo',
]

View File

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

View File

@ -4,6 +4,7 @@ from rest_framework import mixins, permissions, viewsets
from rest_framework import status
from rest_framework.filters import OrderingFilter
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from collection import models, serializers
from utils.views import BindObjectMixin
@ -27,7 +28,7 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
class GuideBaseView(generics.GenericAPIView):
"""ViewSet for Guide model."""
serializer_class = serializers.GuideBaseSerializer
permission_classes = (permissions.IsAuthenticated, )
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get_queryset(self):
"""Overridden get_queryset method."""
@ -43,7 +44,15 @@ class GuideFilterBaseView(generics.GenericAPIView):
pagination_class = None
queryset = models.GuideFilter.objects.all()
serializer_class = serializers.GuideFilterBaseSerializer
permission_classes = (permissions.IsAuthenticated,)
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class GuideElementBaseView(generics.GenericAPIView):
"""Base view for GuideElement model."""
pagination_class = None
queryset = models.GuideElement.objects.all()
serializer_class = serializers.GuideElementBaseSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class CollectionBackOfficeViewSet(mixins.CreateModelMixin,
@ -98,3 +107,14 @@ class GuideFilterCreateView(GuideFilterBaseView,
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'))
return models.GuideElement.objects.get_root_node(guide) \
.get_descendants()

View File

@ -244,8 +244,9 @@ class EstablishmentQuerySet(models.QuerySet):
return Subquery(
self.similar_base(establishment)
.filter(**filters)
.order_by('distance')[:settings.LIMITING_QUERY_OBJECTS]
.values('id')
.order_by('distance')
.distinct()
.values_list('id', flat=True)[:settings.LIMITING_QUERY_OBJECTS]
)
def similar_restaurants(self, slug):
@ -263,7 +264,8 @@ class EstablishmentQuerySet(models.QuerySet):
'establishment_gallery__is_main': True,
}
)
return self.filter(id__in=ids_by_subquery) \
# todo: fix this - replace ids_by_subquery.queryset on ids_by_subquery
return self.filter(id__in=ids_by_subquery.queryset) \
.annotate_intermediate_public_mark() \
.annotate_mark_similarity(mark=restaurant.public_mark) \
.order_by('mark_similarity') \

View File

@ -621,3 +621,33 @@ class CompanyBaseSerializer(serializers.ModelSerializer):
if models.Company.objects.filter(phones__overlap=phones).exists():
raise serializers.ValidationError({'detail': _('Phones is already reserved.')})
return attrs
class EstablishmentGuideElementSerializer(serializers.ModelSerializer):
"""Serializer for Guide serializer."""
type = EstablishmentTypeBaseSerializer(source='establishment_type', read_only=True)
subtypes = EstablishmentSubTypeBaseSerializer(many=True, source='establishment_subtypes')
address = AddressBaseSerializer()
tz = serializers.CharField(read_only=True, source='timezone_as_str')
schedule = ScheduleRUDSerializer(many=True, allow_null=True)
best_price_menu = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
best_price_carte = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
range_price_menu = RangePriceSerializer(read_only=True)
range_price_carte = RangePriceSerializer(read_only=True)
currency = CurrencySerializer()
class Meta(EstablishmentBaseSerializer.Meta):
"""Meta class."""
fields = [
'id',
'type',
'subtypes',
'address',
'tz',
'schedule',
'best_price_menu',
'best_price_carte',
'range_price_menu',
'range_price_carte',
'currency',
]

View File

@ -44,7 +44,7 @@ class EstablishmentListView(EstablishmentMixinView, generics.ListAPIView):
class EstablishmentSimilarView(EstablishmentListView):
"""Resource for getting a list of similar establishments."""
serializer_class = serializers.EstablishmentSimilarSerializer
pagination_class = PortionPagination
pagination_class = None
class EstablishmentRetrieveView(EstablishmentMixinView, generics.RetrieveAPIView):
@ -90,7 +90,7 @@ class RestaurantSimilarListView(EstablishmentSimilarView):
"""Overridden get_queryset method"""
return EstablishmentMixinView.get_queryset(self) \
.has_location() \
.similar_restaurants(slug=self.kwargs.get('slug'))
.similar_restaurants(slug=self.kwargs.get('slug'))[:settings.QUERY_OUTPUT_OBJECTS]
class WinerySimilarListView(EstablishmentSimilarView):
@ -100,7 +100,7 @@ class WinerySimilarListView(EstablishmentSimilarView):
"""Overridden get_queryset method"""
return EstablishmentMixinView.get_queryset(self) \
.has_location() \
.similar_wineries(slug=self.kwargs.get('slug'))
.similar_wineries(slug=self.kwargs.get('slug'))[:settings.QUERY_OUTPUT_OBJECTS]
class ArtisanProducerSimilarListView(EstablishmentSimilarView):
@ -110,7 +110,7 @@ class ArtisanProducerSimilarListView(EstablishmentSimilarView):
"""Overridden get_queryset method"""
return EstablishmentMixinView.get_queryset(self) \
.has_location() \
.similar_artisans_producers(slug=self.kwargs.get('slug'))
.similar_artisans_producers(slug=self.kwargs.get('slug'))[:settings.QUERY_OUTPUT_OBJECTS]
class EstablishmentTypeListView(generics.ListAPIView):

View File

@ -219,3 +219,15 @@ class ProductCommentCreateSerializer(CommentSerializer):
'content_object': validated_data.pop('product')
})
return super().create(validated_data)
class ProductGuideElementSerializer(ProductBaseSerializer):
"""Serializer for serializing in GuideElement for model Product."""
class Meta(ProductBaseSerializer.Meta):
"""Meta class."""
_unused_fields = ('tags', 'wine_regions', 'wine_colors', 'preview_image_url')
fields = ProductBaseSerializer.Meta.fields
# pop unused fields
for unused_field in _unused_fields: fields.pop(fields.index(unused_field))

View File

@ -7,6 +7,7 @@ from product import filters, serializers
from comment.serializers import CommentRUDSerializer
from utils.views import FavoritesCreateDestroyMixinView
from utils.pagination import PortionPagination
from django.conf import settings
class ProductBaseView(generics.GenericAPIView):
@ -97,5 +98,5 @@ class SimilarListView(ProductSimilarView):
"""Overridden get_queryset method."""
return super().get_queryset() \
.has_location() \
.similar(slug=self.kwargs.get('slug'))
.similar(slug=self.kwargs.get('slug'))[:settings.QUERY_OUTPUT_OBJECTS]

View File

@ -72,7 +72,7 @@ class TimeZoneChoiceField(serializers.ChoiceField):
class ProjectModelSerializer(serializers.ModelSerializer):
"""Overrided ModelSerializer."""
"""Overridden ModelSerializer."""
serializers.ModelSerializer.serializer_field_mapping[models.TJSONField] = TJSONField

View File

@ -63,3 +63,6 @@ pycountry==19.8.18
# sql-tree
django-mptt==0.9.1
# For recursive fields
djangorestframework-recursive==0.1.2