gm-127: finished
This commit is contained in:
parent
0e0d6e318e
commit
c4d8b89a8d
|
|
@ -93,15 +93,20 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
"""
|
||||
return self.filter(is_publish=True)
|
||||
|
||||
def annotate_distance(self, point: Point):
|
||||
def has_published_reviews(self):
|
||||
"""
|
||||
Return QuerySet establishments with published reviews.
|
||||
"""
|
||||
return self.filter(reviews__status=Review.READY,)
|
||||
|
||||
def annotate_distance(self, point: Point = None):
|
||||
"""
|
||||
Return QuerySet with annotated field - distance
|
||||
Description:
|
||||
|
||||
"""
|
||||
return self.annotate(distance=models.Value(
|
||||
DistanceMeasure(Distance('address__coordinates', point, srid=4236)).m,
|
||||
output_field=models.FloatField()))
|
||||
return self.annotate(distance=Distance('address__coordinates', point,
|
||||
srid=settings.GEO_DEFAULT_SRID))
|
||||
|
||||
def annotate_intermediate_public_mark(self):
|
||||
"""
|
||||
|
|
@ -110,8 +115,8 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
If establishments in collection POP and its mark is null, then
|
||||
intermediate_mark is set to 10;
|
||||
"""
|
||||
return self.annotate(intermediate_public_mark=models.Case(
|
||||
models.When(
|
||||
return self.annotate(intermediate_public_mark=Case(
|
||||
When(
|
||||
collections__collection_type=Collection.POP,
|
||||
public_mark__isnull=True,
|
||||
then=settings.DEFAULT_ESTABLISHMENT_PUBLIC_MARK
|
||||
|
|
@ -125,8 +130,8 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
Description:
|
||||
Similarity mark determined by comparison with compared establishment mark
|
||||
"""
|
||||
return self.annotate(mark_similarity=models.ExpressionWrapper(
|
||||
mark - models.F('intermediate_public_mark'),
|
||||
return self.annotate(mark_similarity=ExpressionWrapper(
|
||||
mark - F('intermediate_public_mark'),
|
||||
output_field=models.FloatField()
|
||||
))
|
||||
|
||||
|
|
@ -154,6 +159,21 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
else:
|
||||
return self.none()
|
||||
|
||||
def last_reviewed(self, point: Point):
|
||||
"""
|
||||
Return QuerySet with last reviewed establishments.
|
||||
:param point: location Point object, needs to ordering
|
||||
"""
|
||||
subquery_filter_by_distance = Subquery(
|
||||
self.filter(image_url__isnull=False, public_mark__gte=10)
|
||||
.has_published_reviews()
|
||||
.annotate_distance(point=point)
|
||||
.order_by('distance')[:settings.LIMITING_QUERY_NUMBER]
|
||||
.values('id')
|
||||
)
|
||||
return self.filter(id__in=subquery_filter_by_distance) \
|
||||
.order_by('-reviews__published_at')
|
||||
|
||||
def prefetch_actual_employees(self):
|
||||
"""Prefetch actual employees."""
|
||||
return self.prefetch_related(
|
||||
|
|
@ -169,8 +189,8 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
favorite_establishments = user.favorites.by_content_type(app_label='establishment',
|
||||
model='establishment') \
|
||||
.values_list('object_id', flat=True)
|
||||
return self.annotate(in_favorites=models.Case(
|
||||
models.When(
|
||||
return self.annotate(in_favorites=Case(
|
||||
When(
|
||||
id__in=favorite_establishments,
|
||||
then=True),
|
||||
default=False,
|
||||
|
|
@ -194,7 +214,7 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
|||
|
||||
name = models.CharField(_('name'), max_length=255, default='')
|
||||
name_translated = models.CharField(_('Transliterated name'),
|
||||
max_length=255, default='')
|
||||
max_length=255, default='')
|
||||
description = TJSONField(blank=True, null=True, default=None,
|
||||
verbose_name=_('description'),
|
||||
help_text='{"en-GB":"some text"}')
|
||||
|
|
@ -308,6 +328,19 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
|||
return [{'id': tag.metadata.id,
|
||||
'label': tag.metadata.label} for tag in self.tags.all()]
|
||||
|
||||
@property
|
||||
def last_published_review(self):
|
||||
"""Return last published review"""
|
||||
return self.reviews.published()\
|
||||
.order_by('-published_at').first()
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
"""
|
||||
Return Point object of establishment location
|
||||
"""
|
||||
return self.address.coordinates
|
||||
|
||||
|
||||
class Position(BaseAttributes, TranslatedFieldsMixin):
|
||||
"""Position model."""
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ app_name = 'establishment'
|
|||
urlpatterns = [
|
||||
path('', views.EstablishmentListView.as_view(), name='list'),
|
||||
path('tags/', views.EstablishmentTagListView.as_view(), name='tags'),
|
||||
path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(),
|
||||
name='recent-reviews'),
|
||||
path('<slug:slug>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
||||
path('<slug:slug>/similar/', views.EstablishmentSimilarListView.as_view(), name='similar'),
|
||||
path('<slug:slug>/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ class EstablishmentMixin:
|
|||
permission_classes = (permissions.AllowAny,)
|
||||
|
||||
def get_queryset(self):
|
||||
"""Overrided method 'get_queryset'."""
|
||||
"""Overridden method 'get_queryset'."""
|
||||
return models.Establishment.objects.published() \
|
||||
.prefetch_actual_employees()
|
||||
|
|
|
|||
|
|
@ -27,6 +27,25 @@ class EstablishmentListView(EstablishmentMixin, generics.ListAPIView):
|
|||
.annotate_in_favorites(user=self.request.user)
|
||||
|
||||
|
||||
class EstablishmentRecentReviewListView(EstablishmentListView):
|
||||
"""List view for last reviewed establishments."""
|
||||
pagination_class = EstablishmentPortionPagination
|
||||
|
||||
def get_queryset(self):
|
||||
"""Overridden method 'get_queryset'."""
|
||||
qs = super().get_queryset()
|
||||
user_ip = methods.get_user_ip(self.request)
|
||||
query_params = self.request.query_params
|
||||
if 'longitude' in query_params and 'latitude' in query_params:
|
||||
longitude, latitude = query_params.get('longitude'), query_params.get('latitude')
|
||||
else:
|
||||
longitude, latitude = methods.determine_coordinates(user_ip)
|
||||
if not longitude or not latitude:
|
||||
return qs.none()
|
||||
point = Point(x=float(longitude), y=float(latitude), srid=settings.GEO_DEFAULT_SRID)
|
||||
return qs.last_reviewed(point=point)
|
||||
|
||||
|
||||
class EstablishmentSimilarListView(EstablishmentListView):
|
||||
"""Resource for getting a list of establishments."""
|
||||
serializer_class = serializers.EstablishmentListSerializer
|
||||
|
|
|
|||
|
|
@ -327,15 +327,30 @@ FCM_DJANGO_SETTINGS = {
|
|||
|
||||
# Thumbnail settings
|
||||
THUMBNAIL_ALIASES = {
|
||||
'': {
|
||||
'tiny': {'size': (100, 0), },
|
||||
'small': {'size': (480, 0), },
|
||||
'middle': {'size': (700, 0), },
|
||||
'large': {'size': (1500, 0), },
|
||||
'default': {'size': (300, 200), 'crop': True},
|
||||
'gallery': {'size': (240, 160), 'crop': True},
|
||||
'establishment_preview': {'size': (300, 280), 'crop': True},
|
||||
}
|
||||
'news_preview': {
|
||||
'web': {'size': (300, 260), }
|
||||
},
|
||||
'news_promo_horizontal': {
|
||||
'web': {'size': (1900, 600), },
|
||||
'mobile': {'size': (375, 260), },
|
||||
},
|
||||
'news_tile_horizontal': {
|
||||
'web': {'size': (300, 275), },
|
||||
'mobile': {'size': (343, 180), },
|
||||
},
|
||||
'news_tile_vertical': {
|
||||
'web': {'size': (300, 380), },
|
||||
},
|
||||
'news_highlight_vertical': {
|
||||
'web': {'size': (460, 630), },
|
||||
},
|
||||
'news_editor': {
|
||||
'web': {'size': (940, 430), }, # при загрузке через контент эдитор
|
||||
'mobile': {'size': (343, 260), }, # через контент эдитор в мобильном браузерe
|
||||
},
|
||||
'avatar_comments': {
|
||||
'web': {'size': (116, 116), },
|
||||
},
|
||||
}
|
||||
|
||||
# Password reset
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user