From 05770d6d210f09a00eef3ed18b4d6a3d934b424f Mon Sep 17 00:00:00 2001 From: Sicherhaven Date: Mon, 6 Apr 2026 17:25:19 +0530 Subject: [PATCH] feat(carousel): wire is_featured flag to consumer featured events API ConsumerFeaturedEventsView now includes events with is_featured=True alongside ad placement results. Placement events retain priority; is_featured events are appended, deduped, and capped at 10 total. --- ad_control/views.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/ad_control/views.py b/ad_control/views.py index ee3f96e..12dd577 100644 --- a/ad_control/views.py +++ b/ad_control/views.py @@ -9,6 +9,7 @@ import math from datetime import datetime from django.utils import timezone +from django.utils.dateparse import parse_datetime from django.db import models as db_models from django.db.models import Q, Count, Max from rest_framework.views import APIView @@ -58,7 +59,7 @@ def _serialize_picker_event(e): 'endDate': str(e.end_date) if e.end_date else '', 'organizer': e.partner.name if e.partner else 'Eventify', 'organizerLogo': '', - 'category': e.event_type.name if e.event_type else '', + 'category': e.event_type.event_type if e.event_type else '', 'coverImage': cover, 'approvalStatus': 'APPROVED' if e.event_status == 'published' else ( 'REJECTED' if e.event_status == 'cancelled' else 'PENDING' @@ -212,8 +213,8 @@ class PlacementListCreateView(APIView): priority=priority, scope=scope, rank=max_rank + 1, - start_at=datetime.fromisoformat(start_at) if start_at else None, - end_at=datetime.fromisoformat(end_at) if end_at else None, + start_at=parse_datetime(start_at) if start_at else None, + end_at=parse_datetime(end_at) if end_at else None, boost_label=boost_label, notes=notes, created_by=request.user, @@ -243,9 +244,9 @@ class PlacementDetailView(APIView): return JsonResponse({'success': False, 'message': 'Placement not found'}, status=404) if 'startAt' in data: - placement.start_at = datetime.fromisoformat(data['startAt']) if data['startAt'] else None + placement.start_at = parse_datetime(data['startAt']) if data['startAt'] else None if 'endAt' in data: - placement.end_at = datetime.fromisoformat(data['endAt']) if data['endAt'] else None + placement.end_at = parse_datetime(data['endAt']) if data['endAt'] else None if 'scope' in data: placement.scope = data['scope'] if 'priority' in data: @@ -507,8 +508,27 @@ class ConsumerFeaturedEventsView(APIView): user_lng=user_lng, ) + # IDs already covered by ad placements (used for dedup) + placement_ids = {p.event_id for p in placements} + + # Start with placement events (they take priority) events = [_serialize_event_for_consumer(p.event) for p in placements] + # Append is_featured events that aren't already in the placement set + featured_qs = ( + Event.objects + .filter(is_featured=True, event_status='published') + .exclude(id__in=placement_ids) + .order_by('-start_date', '-created_date') + ) + for evt in featured_qs: + if len(events) >= 10: + break + events.append(_serialize_event_for_consumer(evt)) + + # Cap at 10 total + events = events[:10] + return JsonResponse({'status': 'success', 'events': events}) except Exception as e: return JsonResponse({'status': 'error', 'message': str(e)}, status=500)