"""Establishment app views.""" from django.conf import settings from django.contrib.gis.geos import Point from django.shortcuts import get_object_or_404 from rest_framework import generics, permissions from comment import models as comment_models from comment.serializers import CommentRUDSerializer from establishment import filters, models, serializers from main import methods from utils.pagination import EstablishmentPortionPagination from utils.views import FavoritesCreateDestroyMixinView class EstablishmentMixinView: """Establishment mixin.""" permission_classes = (permissions.AllowAny,) def get_queryset(self): """Overridden method 'get_queryset'.""" qs = models.Establishment.objects.published() \ .with_base_related() \ .annotate_in_favorites(self.request.user) if self.request.country_code: qs = qs.by_country_code(self.request.country_code) return qs class EstablishmentListView(EstablishmentMixinView, generics.ListAPIView): """Resource for getting a list of establishments.""" filter_class = filters.EstablishmentFilter serializer_class = serializers.EstablishmentListRetrieveSerializer def get_queryset(self): return super().get_queryset().with_schedule()\ .with_extended_address_related().with_currency_related() class EstablishmentRetrieveView(EstablishmentMixinView, generics.RetrieveAPIView): """Resource for getting a establishment.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentDetailSerializer def get_queryset(self): return super().get_queryset().with_extended_related() 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.EstablishmentSimilarSerializer pagination_class = EstablishmentPortionPagination def get_queryset(self): """Override get_queryset method""" qs = super().get_queryset() return qs.similar(establishment_slug=self.kwargs.get('slug')) class EstablishmentTypeListView(generics.ListAPIView): """Resource for getting a list of establishment types.""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentTypeBaseSerializer queryset = models.EstablishmentType.objects.all() class EstablishmentCommentCreateView(generics.CreateAPIView): """View for create new comment.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentCommentCreateSerializer queryset = comment_models.Comment.objects.all() class EstablishmentCommentListView(generics.ListAPIView): """View for return list of establishment comments.""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentCommentCreateSerializer def get_queryset(self): """Override get_queryset method""" establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug']) return comment_models.Comment.objects.by_content_type(app_label='establishment', model='establishment')\ .by_object_id(object_id=establishment.pk)\ .order_by('-created') class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView): """View for retrieve/update/destroy establishment comment.""" serializer_class = CommentRUDSerializer queryset = models.Establishment.objects.all() def get_object(self): """ Returns the object the view is displaying. """ queryset = self.filter_queryset(self.get_queryset()) establishment_obj = get_object_or_404(queryset, slug=self.kwargs['slug']) comment_obj = get_object_or_404(establishment_obj.comments.by_user(self.request.user), pk=self.kwargs['comment_id']) # May raise a permission denied self.check_object_permissions(self.request, comment_obj) return comment_obj class EstablishmentFavoritesCreateDestroyView(FavoritesCreateDestroyMixinView): """View for create/destroy establishment from favorites.""" _model = models.Establishment serializer_class = serializers.EstablishmentFavoritesCreateSerializer class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIView): """Resource for getting list of nearest establishments.""" serializer_class = serializers.EstablishmentGeoSerializer filter_class = filters.EstablishmentFilter def get_queryset(self): """Overridden method 'get_queryset'.""" # todo: latitude and longitude lat = self.request.query_params.get('lat') lon = self.request.query_params.get('lon') radius = self.request.query_params.get('radius') unit = self.request.query_params.get('unit') qs = super(EstablishmentNearestRetrieveView, self).get_queryset() if lat and lon and radius and unit: center = Point(float(lon), float(lat)) filter_kwargs = {'center': center, 'radius': float(radius), 'unit': unit} return qs.by_distance_from_point(**{k: v for k, v in filter_kwargs.items() if v is not None}) return qs