Merge pull request #77 from WDI-Ideas/development
feat(filter): fixed nearest, latest and preference event
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user