diff --git a/goodtimes/services.py b/goodtimes/services.py index c28b41c..6488f7e 100644 --- a/goodtimes/services.py +++ b/goodtimes/services.py @@ -806,17 +806,24 @@ class GoogleMapsservice: if element["status"] == "OK" and element["distance"]["value"] <= radius_km * 1000 # Convert km to meters } + print(f"distance is {distances} and distances key is {distances.keys()}") + # Filter the queryset to include only events within the specified radius queryset = queryset.filter(id__in=distances.keys()) - # # Sort the event IDs by their distances in ascending order - # event_ids_by_distance = sorted(distances, key=distances.get) + print(f"query set after distance filter {queryset}") - # # Create a Case/When expression to preserve the order of events by distance - # preserved_order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(event_ids_by_distance)]) - # print(f"preserved_order is {preserved_order}") - # # Order the queryset based on the preserved order - # queryset = queryset.order_by(preserved_order) + # Sort the event IDs by their distances in ascending order + event_ids_by_distance = sorted(distances, key=distances.get) + print(f"sort event by it distance {event_ids_by_distance}") + + # Create a Case/When expression to preserve the order of events by distance + preserved_order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(event_ids_by_distance)]) + print(f"preserved_order is {preserved_order}") + # Order the queryset based on the preserved order + queryset = queryset.order_by(preserved_order) + for data in queryset: + print(f"queryset after preserverd order {data.id}") return queryset diff --git a/manage_events/api/serializers.py b/manage_events/api/serializers.py index 4529224..30982b0 100644 --- a/manage_events/api/serializers.py +++ b/manage_events/api/serializers.py @@ -50,6 +50,18 @@ class EventCategorySerializer(serializers.ModelSerializer): model = EventCategory fields = ["id", "title", "image", "description", "video_url"] + def get_image_url(self, obj, field_name, request): + image_field = getattr(obj, field_name) + if image_field: + return request.build_absolute_uri(image_field.url) + return "" + + def to_representation(self, instance): + data = super().to_representation(instance) + request = self.context.get("request") + data["image"] = self.get_image_url(instance, "image", request) + return data + class AgeGroupsSerializer(serializers.ModelSerializer): class Meta: model = AgeGroups diff --git a/manage_events/api/views.py b/manage_events/api/views.py index 860c65f..73f71a7 100644 --- a/manage_events/api/views.py +++ b/manage_events/api/views.py @@ -586,7 +586,7 @@ class EventPreferencesView(APIView): def get(self, request, *args, **kwargs): """Get all event categories for the authenticated user.""" obj = self.model.objects.filter(active=True, deleted=False) - serializer = self.serializer_class(obj, many=True) + serializer = self.serializer_class(obj, many=True, context={"request": request}) return ApiResponse.success( data=serializer.data, message=constants.SUCCESS, status=status.HTTP_200_OK ) @@ -1004,65 +1004,77 @@ class AgeGroupListView(APIView): class EventListView(generics.ListAPIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] - queryset = Event.objects.filter(active=True, draft=False, deleted=False, end_date__gte=timezone.now().date()) serializer_class = EventListSerializer filter_backends = [DjangoFilterBackend] filterset_class = EventFilter - def apply_popularity_latest(self, queryset, ordering): - # Split the ordering fields and remove any leading '-' characters - ordering_fields = [field.lstrip("-") for field in ordering.split(",")] - - # Check if 'nearest' is in the ordering fields and remove it as nearest work only for lat and longitude - if "nearest" in ordering_fields: - ordering.replace("nearest", "") - ordering_fields.remove("nearest") - - # Annotate the queryset with popularity if 'popularity' is in the ordering fields - if "popularity" in ordering_fields: - queryset = queryset.annotate(popularity=Count("interaction_event")) - - # Replace 'latest' with '-created_on' in the ordering fields - ordering = ",".join( - "start_date" if field == "latest" else f"-{field}" - for field in ordering_fields - ) - - # If ordering is empty, set a default ordering - if not ordering: - ordering = "-start_date" - - print(f"++++++++++++++++++++++++++++++++ordering data in populatirn flow {ordering}") - # Apply the ordering to the queryset - return queryset.order_by(*ordering.split(",")) - def get_queryset(self): - queryset = super().get_queryset() + # Base queryset filtering active, non-draft, non-deleted events with end date in the future + print(f"queryparams is {self.request.query_params}") - # Sort by nearest location if latitude and longitude are provided + if self.request.query_params: + queryset = Event.objects.filter( + active=True, + draft=False, + deleted=False, + end_date__gte=timezone.now().date() + ) + else: + preferences = PrincipalPreference.objects.get(principal=self.request.user) + preferred_categories_ids = preferences.preferred_categories.values_list( + "id", flat=True + ) + queryset = Event.objects.filter( + active=True, + draft=False, + deleted=False, + end_date__gte=timezone.now().date(), + category__in=preferred_categories_ids + ) + + # Get query parameters latitude = self.request.query_params.get("latitude") longitude = self.request.query_params.get("longitude") - ordering = self.request.query_params.get("ordering", "") + ordering = self.request.query_params.get("sort", "") + # Handle nearest location sorting if latitude and longitude and "nearest" in ordering: - print("latitude fucntion called") - gmaps_service = GoogleMapsservice() - queryset = gmaps_service.get_nearest_events(queryset, float(latitude), float(longitude)) + queryset = self.apply_nearest_filter(queryset, latitude, longitude) - print(f"=======orderring data is {ordering}") + # Handle popularity and latest sorting + # if ordering: + queryset = self.apply_popularity_latest(queryset, ordering) + + return queryset + + def apply_nearest_filter(self, queryset, latitude, longitude): + gmaps_service = GoogleMapsservice() + return gmaps_service.get_nearest_events(queryset, float(latitude), float(longitude)) + + def apply_popularity_latest(self, queryset, ordering): + # Split ordering fields and process each field + ordering_fields = [field.lstrip("-") for field in ordering.split(",")] + + # Remove 'nearest' from ordering as it's handled separately + if "nearest" in ordering_fields: + ordering_fields.remove("nearest") + ordering = ordering.replace("nearest", "") + + # Annotate with popularity and order it if requested + if "popularity" in ordering_fields: + queryset = queryset.annotate(popularity=Count("interaction_event")).order_by("-popularity") + + # order latest record and by default sorting + queryset = queryset.order_by("start_date") - # Apply popularity annotation and ordering if requested - if ordering: - queryset = self.apply_popularity_latest(queryset, ordering) return queryset def get(self, request, *args, **kwargs): - print(f"getquery set data is {self.get_queryset()}") queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) - data = self.get_paginated_response(serializer.data) - return ApiResponse.success(message=constants.SUCCESS, data=data) + return self.get_paginated_response(serializer.data) + serializer = self.get_serializer(queryset, many=True) return ApiResponse.success(message=constants.SUCCESS, data=serializer.data) \ No newline at end of file