Merge pull request #77 from WDI-Ideas/development

feat(filter): fixed nearest, latest and preference event
This commit is contained in:
BOBBY VISHWAKARMA
2024-07-29 15:42:09 +05:30
committed by GitHub
3 changed files with 80 additions and 49 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)