GM-127: in progress

This commit is contained in:
Anatoly 2019-09-25 19:39:37 +03:00
parent 8766388256
commit 207e35feb1
6 changed files with 44 additions and 35 deletions

View File

@ -1,18 +1,20 @@
"""Establishment models."""
from functools import reduce
from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.measure import Distance as DistanceMeasure
from django.contrib.gis.geos import Point
from django.conf import settings
from django.contrib.contenttypes import fields as generic
from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance as DistanceMeasure
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import When, Case, F, ExpressionWrapper, Subquery
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from location.models import Address
from collection.models import Collection
from location.models import Address
from review.models import Review
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField, URLImageMixin,
TranslatedFieldsMixin, BaseAttributes)
@ -128,27 +130,28 @@ class EstablishmentQuerySet(models.QuerySet):
output_field=models.FloatField()
))
def similar(self, establishment_slug: str, output_objects: int = 12):
def similar(self, establishment_slug: str):
"""
Return QuerySet with objects that similar to Establishment.
:param establishment_slug: str Establishment slug
:param output_objects: int of output objects
"""
establishment_qs = Establishment.objects.filter(slug=establishment_slug,
public_mark__isnull=False)
if establishment_qs.exists():
establishment = establishment_qs.first()
return self.exclude(slug=establishment_slug) \
.filter(is_publish=True,
image_url__isnull=False,
reviews__isnull=False,
reviews__status=Review.READY,
public_mark__gte=10) \
.annotate_distance(point=establishment.address.coordinates) \
subquery_filter_by_distance = Subquery(
self.exclude(slug=establishment_slug)
.filter(image_url__isnull=False, public_mark__gte=10)
.published()
.has_published_reviews()
.annotate_distance(point=establishment.address.coordinates)
.order_by('distance')[:settings.LIMITING_QUERY_NUMBER]
.values('id')
)
return Establishment.objects.filter(id__in=subquery_filter_by_distance) \
.annotate_intermediate_public_mark() \
.annotate_mark_similarity(mark=establishment.public_mark) \
.order_by('distance') \
.order_by('mark_similarity')[:output_objects]
.order_by('mark_similarity')
else:
return self.none()

View File

@ -191,7 +191,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
schedule = ScheduleRUDSerializer(many=True, allow_null=True)
phones = ContactPhonesSerializer(read_only=True, many=True, )
emails = ContactEmailsSerializer(read_only=True, many=True, )
review = serializers.SerializerMethodField()
review = ReviewSerializer(source='last_published_review', allow_null=True)
employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees',
many=True)
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
@ -201,7 +201,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
slug = serializers.SlugField(required=True, allow_blank=False, max_length=50)
in_favorites = serializers.SerializerMethodField()
in_favorites = serializers.BooleanField()
image = serializers.URLField(source='image_url')
@ -231,21 +231,6 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
'slug',
]
def get_review(self, obj):
"""Serializer method for getting last published review"""
return ReviewSerializer(obj.reviews.by_status(status=review_models.Review.READY)
.order_by('-published_at').first()).data
def get_in_favorites(self, obj):
"""Get in_favorites status flag"""
user = self.context.get('request').user
if user.is_authenticated:
return obj.id in user.favorites.by_content_type(app_label='establishment',
model='establishment')\
.values_list('object_id', flat=True)
else:
return False
class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer):
"""Create comment serializer"""

View File

@ -9,6 +9,7 @@ from establishment import filters
from establishment import models, serializers
from establishment.views import EstablishmentMixin
from main.models import MetaDataContent
from utils.pagination import EstablishmentPagination
from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer
@ -27,10 +28,12 @@ class EstablishmentListView(EstablishmentMixin, generics.ListAPIView):
class EstablishmentSimilarListView(EstablishmentListView):
"""Resource for getting a list of establishments."""
serializer_class = serializers.EstablishmentListSerializer
pagination_class = EstablishmentPagination
def get_queryset(self):
"""Override get_queryset method"""
return super().get_queryset().similar(establishment_slug=self.kwargs.get('slug'))
return super().get_queryset() \
.similar(establishment_slug=self.kwargs.get('slug'))
class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView):
@ -38,6 +41,11 @@ class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView):
lookup_field = 'slug'
serializer_class = serializers.EstablishmentDetailSerializer
def get_queryset(self):
"""Override 'get_queryset' method."""
return super(EstablishmentRetrieveView, self).get_queryset() \
.annotate_in_favorites(self.request.user)
class EstablishmentTypeListView(generics.ListAPIView):
"""Resource for getting a list of establishment types."""

View File

@ -23,6 +23,10 @@ class ReviewQuerySet(models.QuerySet):
"""Filter by status"""
return self.filter(status=status)
def published(self):
"""Return published reviews"""
return self.filter(status=Review.READY)
class Review(BaseAttributes, TranslatedFieldsMixin):
"""Review model"""

View File

@ -44,3 +44,10 @@ class ProjectMobilePagination(ProjectPageNumberPagination):
if not self.page.has_previous():
return None
return self.page.previous_page_number()
class EstablishmentPagination(ProjectMobilePagination):
"""
Pagination for app establishments with limit page size equal to 12
"""
page_size = 12

View File

@ -412,3 +412,5 @@ SOLO_CACHE_TIMEOUT = 300
SITE_REDIRECT_URL_UNSUBSCRIBE = '/unsubscribe/'
SITE_NAME = 'Gault & Millau'
LIMITING_QUERY_NUMBER = 36 # Need to restrict objects to sort (used in establishments)