added two endpoints: /.../establishments/slug/{slug}/similar/producers/food/, /.../establishments/slug/{slug}/similar/artisans/distilleries/

This commit is contained in:
Anatoly 2020-01-10 17:20:50 +03:00
parent de35a1c0d5
commit db8917e7af
3 changed files with 91 additions and 19 deletions

View File

@ -254,8 +254,6 @@ class EstablishmentQuerySet(models.QuerySet):
if establishment.establishment_subtypes.exists():
filters.update(
{'establishment_subtypes__in': establishment.establishment_subtypes.all()})
if establishment.address and establishment.address.coordinates:
qs = qs.annotate_distance(point=establishment.location)
return qs
def similar_base_subquery(self, establishment, filters: dict) -> Subquery:
@ -269,7 +267,8 @@ class EstablishmentQuerySet(models.QuerySet):
.filter(**filters)
if establishment.address and establishment.address.coordinates:
return Subquery(
qs.order_by('distance')
qs.annotate_distance(point=establishment.location)
.order_by('distance')
.distinct()
.values_list('id', flat=True)[:settings.LIMITING_QUERY_OBJECTS]
)
@ -292,10 +291,10 @@ class EstablishmentQuerySet(models.QuerySet):
}
)
return self.filter(id__in=ids_by_subquery.queryset) \
.annotate_intermediate_public_mark() \
.annotate_mark_similarity(mark=restaurant.public_mark) \
.order_by('mark_similarity') \
.distinct('mark_similarity', 'id')
.annotate_intermediate_public_mark() \
.annotate_mark_similarity(mark=restaurant.public_mark) \
.order_by('mark_similarity') \
.distinct('mark_similarity', 'id')
def same_subtype(self, establishment):
"""Annotate flag same subtype."""
@ -313,19 +312,19 @@ class EstablishmentQuerySet(models.QuerySet):
Return QuerySet with objects that similar to Artisan/Producer(s).
:param establishment: Establishment instance
"""
base_qs = self.similar_base(establishment).same_subtype(establishment)
similarity_rules = {
'ordering': [F('same_subtype').desc(), ],
'distinctions': ['same_subtype', ]
}
if establishment.address and establishment.address.coordinates:
base_qs = base_qs.annotate_distance(point=establishment.location)
similarity_rules['ordering'].append(F('distance').asc())
similarity_rules['distinctions'].append('distance')
return self.similar_base(establishment) \
.same_subtype(establishment) \
.has_published_reviews() \
.order_by(*similarity_rules['ordering']) \
.distinct(*similarity_rules['distinctions'], 'id')
return base_qs.has_published_reviews() \
.order_by(*similarity_rules['ordering']) \
.distinct(*similarity_rules['distinctions'], 'id')
def by_wine_region(self, wine_region):
"""
@ -346,6 +345,7 @@ class EstablishmentQuerySet(models.QuerySet):
Return QuerySet with objects that similar to Winery.
:param winery: Establishment instance
"""
base_qs = self.similar_base(winery)
similarity_rules = {
'ordering': [F('wine_origins__wine_region').asc(),
F('wine_origins__wine_sub_region').asc()],
@ -353,13 +353,50 @@ class EstablishmentQuerySet(models.QuerySet):
'wine_origins__wine_sub_region']
}
if winery.address and winery.address.coordinates:
base_qs = base_qs.annotate_distance(point=winery.location)
similarity_rules['ordering'].append(F('distance').asc())
similarity_rules['distinctions'].append('distance')
return self.similar_base(winery) \
.order_by(*similarity_rules['ordering']) \
.distinct(*similarity_rules['distinctions'],
'id')
return base_qs.order_by(*similarity_rules['ordering']) \
.distinct(*similarity_rules['distinctions'], 'id')
def similar_distilleries(self, distillery):
"""
Return QuerySet with objects that similar to Distillery.
:param distillery: Establishment instance
"""
base_qs = self.similar_base(distillery).same_subtype(distillery)
similarity_rules = {
'ordering': [F('same_subtype').desc(), ],
'distinctions': ['same_subtype', ]
}
if distillery.address and distillery.address.coordinates:
base_qs = base_qs.annotate_distance(point=distillery.location)
similarity_rules['ordering'].append(F('distance').asc())
similarity_rules['distinctions'].append('distance')
return base_qs.published() \
.has_published_reviews() \
.order_by(*similarity_rules['ordering']) \
.distinct(*similarity_rules['distinctions'], 'id')
def similar_food_producers(self, distillery):
"""
Return QuerySet with objects that similar to Food Producer.
:param distillery: Establishment instance
"""
base_qs = self.similar_base(distillery).same_subtype(distillery)
similarity_rules = {
'ordering': [F('same_subtype').desc(), ],
'distinctions': ['same_subtype', ]
}
if distillery.address and distillery.address.coordinates:
base_qs = base_qs.annotate_distance(point=distillery.location)
similarity_rules['ordering'].append(F('distance').asc())
similarity_rules['distinctions'].append('distance')
return base_qs.order_by(*similarity_rules['ordering']) \
.distinct(*similarity_rules['distinctions'], 'id')
def last_reviewed(self, point: Point):
"""

View File

@ -9,7 +9,8 @@ urlpatterns = [
path('', views.EstablishmentListView.as_view(), name='list'),
path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(),
name='recent-reviews'),
path('slug/<slug:slug>/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'),
path('slug/<slug:slug>/comments/', views.EstablishmentCommentListView.as_view(),
name='list-comments'),
path('slug/<slug:slug>/comments/create/', views.EstablishmentCommentCreateView.as_view(),
name='create-comment'),
path('slug/<slug:slug>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
@ -22,9 +23,15 @@ urlpatterns = [
name='similar-restaurants'),
path('slug/<slug:slug>/similar/wineries/', views.WinerySimilarListView.as_view(),
name='similar-wineries'),
# temporary uses single mechanism, bec. description in process
path('slug/<slug:slug>/similar/artisans/', views.ArtisanProducerSimilarListView.as_view(),
name='similar-artisans'),
path('slug/<slug:slug>/similar/artisans/distilleries/',
views.DistillerySimilarListView.as_view(),
name='similar-distilleries'),
path('slug/<slug:slug>/similar/producers/', views.ArtisanProducerSimilarListView.as_view(),
name='similar-producers'),
path('slug/<slug:slug>/similar/producers/food/', views.FoodProducerSimilarListView.as_view(),
name='similar-food-producers'),
]

View File

@ -139,10 +139,38 @@ class ArtisanProducerSimilarListView(EstablishmentSimilarView):
return qs.none()
class DistillerySimilarListView(EstablishmentSimilarView):
"""Resource for getting a list of similar distillery(s)."""
def get_queryset(self):
"""Overridden get_queryset method"""
qs = super(DistillerySimilarListView, self).get_queryset()
base_establishment = self.get_base_object()
if base_establishment:
return qs.similar_distilleries(base_establishment)[:settings.QUERY_OUTPUT_OBJECTS]
else:
return qs.none()
class FoodProducerSimilarListView(EstablishmentSimilarView):
"""Resource for getting a list of similar food producers(s)."""
def get_queryset(self):
"""Overridden get_queryset method"""
qs = super(FoodProducerSimilarListView, self).get_queryset()
base_establishment = self.get_base_object()
if base_establishment:
return qs.similar_food_producers(base_establishment)[:settings.QUERY_OUTPUT_OBJECTS]
else:
return qs.none()
class EstablishmentTypeListView(generics.ListAPIView):
"""Resource for getting a list of establishment types."""
permission_classes = (permissions.AllowAny,)
permission_classes = (permissions.AllowAny, )
serializer_class = serializers.EstablishmentTypeBaseSerializer
queryset = models.EstablishmentType.objects.all()