diff --git a/apps/establishment/models.py b/apps/establishment/models.py index efe665ef..a0c9c44c 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -102,6 +102,20 @@ class EstablishmentQuerySet(models.QuerySet): default=False, output_field=models.BooleanField(default=False))) + def by_distance_from_point(self, center, radius, unit='m'): + """ + Returns nearest establishments + + :param center: point from which to find nearby establishments + :param radius: the maximum distance within the radius of which to look for establishments + :return: all establishments within the specified radius of specified point + :param unit: length unit e.g. m, km. Default is 'm'. + """ + + from django.contrib.gis.measure import Distance + kwargs = {unit: radius} + return self.filter(address__coordinates__distance_lte=(center, Distance(**kwargs))) + class Establishment(ProjectBaseMixin, ImageMixin, TranslatedFieldsMixin): """Establishment model.""" diff --git a/apps/establishment/urls/common.py b/apps/establishment/urls/common.py index 007f7802..dc96c542 100644 --- a/apps/establishment/urls/common.py +++ b/apps/establishment/urls/common.py @@ -5,7 +5,6 @@ from establishment import views app_name = 'establishment' - urlpatterns = [ path('', views.EstablishmentListView.as_view(), name='list'), path('tags/', views.EstablishmentTagListView.as_view(), name='tags'), @@ -16,5 +15,5 @@ urlpatterns = [ path('/comments//', views.EstablishmentCommentRUDView.as_view(), name='rud-comment'), path('/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(), - name='add-favorites'), -] \ No newline at end of file + name='add-favorites') +] diff --git a/apps/establishment/urls/mobile.py b/apps/establishment/urls/mobile.py new file mode 100644 index 00000000..2803be18 --- /dev/null +++ b/apps/establishment/urls/mobile.py @@ -0,0 +1,11 @@ +"""Establishment url patterns.""" +from django.urls import path + +from establishment import views +from establishment.urls.common import urlpatterns as common_urlpatterns + +urlpatterns = [ + path('geo/', views.EstablishmentNearestRetrieveView.as_view(), name='nearest-establishments-list') +] + +urlpatterns.extend(common_urlpatterns) diff --git a/apps/establishment/views.py b/apps/establishment/views.py index 379407bd..96fbf0f5 100644 --- a/apps/establishment/views.py +++ b/apps/establishment/views.py @@ -120,6 +120,25 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D return obj +class EstablishmentNearestRetrieveView(EstablishmentMixin, JWTGenericViewMixin, generics.ListAPIView): + """Resource for getting list of nearest establishments.""" + serializer_class = serializers.EstablishmentListSerializer + filter_class = filters.EstablishmentFilter + + def get_queryset(self): + """Overrided method 'get_queryset'.""" + from django.contrib.gis.geos import Point + + center = Point(float(self.request.query_params["lat"]), float(self.request.query_params["lon"])) + radius = float(self.request.query_params["radius"]) + unit = self.request.query_params.get("unit", None) + by_distance_from_point_kwargs = {"center": center, "radius": radius, "unit": unit} + return super(EstablishmentNearestRetrieveView, self).get_queryset() \ + .by_distance_from_point(**{k: v for k, v in by_distance_from_point_kwargs.items() if v is not None}) \ + .by_country_code(code=self.request.country_code) \ + .annotate_in_favorites(user=self.request.user) + + class EstablishmentTagListView(generics.ListAPIView): """List view for establishment tags.""" serializer_class = serializers.EstablishmentTagListSerializer diff --git a/project/urls/mobile.py b/project/urls/mobile.py index c007e260..0bcbd31c 100644 --- a/project/urls/mobile.py +++ b/project/urls/mobile.py @@ -3,10 +3,11 @@ from django.urls import path, include app_name = 'mobile' urlpatterns = [ + path('establishments/', include('establishment.urls.mobile')), # path('account/', include('account.urls.web')), # path('advertisement/', include('advertisement.urls.web')), # path('collection/', include('collection.urls.web')), # path('establishments/', include('establishment.urls.web')), # path('news/', include('news.urls.web')), # path('partner/', include('partner.urls.web')), -] \ No newline at end of file +]