refactored the mechanism for finding similar establishments
This commit is contained in:
parent
b58d54c07e
commit
e2ec179f69
|
|
@ -213,7 +213,13 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
))
|
||||
|
||||
def similar_base(self, establishment):
|
||||
|
||||
"""
|
||||
Return filtered QuerySet by base filters.
|
||||
Filters including:
|
||||
1 Filter by type (and subtype) establishment.
|
||||
2 Filter by published Review.
|
||||
3 With annotated distance.
|
||||
"""
|
||||
filters = {
|
||||
'reviews__status': Review.READY,
|
||||
'establishment_type': establishment.establishment_type,
|
||||
|
|
@ -224,27 +230,64 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
.filter(**filters) \
|
||||
.annotate_distance(point=establishment.location)
|
||||
|
||||
def similar_base_subquery(self, establishment, filters: dict) -> Subquery:
|
||||
"""
|
||||
Return filtered Subquery object by filters.
|
||||
Filters including:
|
||||
1 Filter by transmitted filters.
|
||||
2 With ordering by distance.
|
||||
"""
|
||||
return Subquery(
|
||||
self.similar_base(establishment)
|
||||
.filter(**filters)
|
||||
.order_by('distance')[:settings.LIMITING_QUERY_OBJECTS]
|
||||
.values('id')
|
||||
)
|
||||
|
||||
def similar_restaurants(self, slug):
|
||||
"""
|
||||
Return QuerySet with objects that similar to Restaurant.
|
||||
:param restaurant_slug: str Establishment slug
|
||||
:param slug: str restaurant slug
|
||||
"""
|
||||
restaurant_qs = self.filter(slug=slug,
|
||||
public_mark__isnull=False)
|
||||
restaurant_qs = self.filter(slug=slug)
|
||||
if restaurant_qs.exists():
|
||||
establishment = restaurant_qs.first()
|
||||
subquery_filter_by_distance = Subquery(
|
||||
self.similar_base(establishment)
|
||||
.filter(public_mark__gte=10,
|
||||
establishment_gallery__is_main=True)
|
||||
.order_by('distance')[:settings.LIMITING_QUERY_OBJECTS]
|
||||
.values('id')
|
||||
restaurant = restaurant_qs.first()
|
||||
ids_by_subquery = self.similar_base_subquery(
|
||||
establishment=restaurant,
|
||||
filters={
|
||||
'public_mark__gte': 10,
|
||||
'establishment_gallery__is_main': True,
|
||||
}
|
||||
)
|
||||
return self.filter(id__in=subquery_filter_by_distance) \
|
||||
return self.filter(id__in=ids_by_subquery) \
|
||||
.annotate_intermediate_public_mark() \
|
||||
.annotate_mark_similarity(mark=establishment.public_mark) \
|
||||
.annotate_mark_similarity(mark=restaurant.public_mark) \
|
||||
.order_by('mark_similarity') \
|
||||
.distinct('mark_similarity', 'id')
|
||||
else:
|
||||
return self.none()
|
||||
|
||||
def similar_artisans(self, slug):
|
||||
"""
|
||||
Return QuerySet with objects that similar to Artisan.
|
||||
:param slug: str artisan slug
|
||||
"""
|
||||
artisan_qs = self.filter(slug=slug)
|
||||
if artisan_qs.exists():
|
||||
artisan = artisan_qs.first()
|
||||
ids_by_subquery = self.similar_base_subquery(
|
||||
establishment=artisan,
|
||||
filters={
|
||||
'public_mark__gte': 10,
|
||||
}
|
||||
)
|
||||
return self.filter(id__in=ids_by_subquery) \
|
||||
.annotate_intermediate_public_mark() \
|
||||
.annotate_mark_similarity(mark=artisan.public_mark) \
|
||||
.order_by('mark_similarity') \
|
||||
.distinct('mark_similarity', 'id')
|
||||
else:
|
||||
return self.none()
|
||||
|
||||
def by_wine_region(self, wine_region):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ urlpatterns = [
|
|||
path('slug/<slug:slug>/similar/', views.RestaurantSimilarListView.as_view(),
|
||||
name='similar-restaurants'),
|
||||
path('slug/<slug:slug>/similar/wineries/', views.WinerySimilarListView.as_view(),
|
||||
name='similar-restaurants'),
|
||||
name='similar-wineries'),
|
||||
path('slug/<slug:slug>/similar/artisans/', views.ArtisanSimilarListView.as_view(),
|
||||
name='similar-artisans'),
|
||||
|
||||
]
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class RestaurantSimilarListView(EstablishmentSimilarList):
|
|||
"""Resource for getting a list of similar restaurants."""
|
||||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method"""
|
||||
"""Overridden get_queryset method"""
|
||||
return EstablishmentMixinView.get_queryset(self) \
|
||||
.similar_restaurants(slug=self.kwargs.get('slug'))
|
||||
|
||||
|
|
@ -96,11 +96,20 @@ class WinerySimilarListView(EstablishmentSimilarList):
|
|||
"""Resource for getting a list of similar wineries."""
|
||||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method"""
|
||||
"""Overridden get_queryset method"""
|
||||
return EstablishmentMixinView.get_queryset(self) \
|
||||
.similar_wineries(slug=self.kwargs.get('slug'))
|
||||
|
||||
|
||||
class ArtisanSimilarListView(EstablishmentSimilarList):
|
||||
"""Resource for getting a list of similar artisans."""
|
||||
|
||||
def get_queryset(self):
|
||||
"""Overridden get_queryset method"""
|
||||
return EstablishmentMixinView.get_queryset(self) \
|
||||
.similar_artisans(slug=self.kwargs.get('slug'))
|
||||
|
||||
|
||||
class EstablishmentTypeListView(generics.ListAPIView):
|
||||
"""Resource for getting a list of establishment types."""
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user