feat: add user search/filter, banned metric, mobile review API, event detail improvements

- admin_api/views.py: Add banned count to UserMetrics, fix server-side search/filter in UserListView
- admin_api/models.py: Add ReviewInteraction model, display_name/is_verified/helpful_count/flag_count to Review
- mobile_api/views/reviews.py: Customer-facing review submit/list/helpful/flag endpoints
- mobile_api/urls.py: Wire review API routes
- mobile_api/views/events.py: Event detail and listing improvements
- Security hardening across API modules
This commit is contained in:
2026-03-26 09:50:03 +00:00
parent f8c17e2c8d
commit 4cf70b6330
11 changed files with 371 additions and 91 deletions

View File

@@ -1,7 +1,8 @@
import json
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.permissions import IsAuthenticated, AllowAny
from events.models import Event, EventImages
from master_data.models import EventType
from django.forms.models import model_to_dict
@@ -15,93 +16,83 @@ from mobile_api.utils import validate_token_and_get_user
@method_decorator(csrf_exempt, name='dispatch')
class EventTypeListAPIView(APIView):
permission_classes = [AllowAny]
def post(self, request):
try:
user, token, data, error_response = validate_token_and_get_user(request)
if error_response:
return error_response
# Fetch event types manually without serializer
event_types_queryset = EventType.objects.all()
event_types = []
for event_type in event_types_queryset:
event_type_data = {
"id": event_type.id,
"event_type": event_type.event_type,
"event_type_icon": request.build_absolute_uri(event_type.event_type_icon.url) if event_type.event_type_icon else None
"event_type_icon": event_type.event_type_icon.url if event_type.event_type_icon else None
}
event_types.append(event_type_data)
print(event_types)
return JsonResponse({
"status": "success",
"event_types": event_types
})
return JsonResponse({"status": "success", "event_types": event_types})
except Exception as e:
return JsonResponse(
{"status": "error", "message": str(e)},
)
return JsonResponse({"status": "error", "message": str(e)})
class EventListAPI(APIView):
permission_classes = [AllowAny]
def post(self, request):
try:
print('*' * 100)
print(request.body)
print('*' * 100)
user, token, data, error_response = validate_token_and_get_user(request)
if error_response:
return error_response
try:
data = json.loads(request.body) if request.body else {}
except Exception:
data = {}
pincode = data.get("pincode")
print('*' * 100)
print(pincode)
print('*' * 100)
# pincode is optional - if not provided or 'all', return all events
paginate = "page" in data
page = int(data.get("page", 1))
page_size = int(data.get("page_size", 15))
events = Event.objects.select_related('event_type').order_by('-created_date')
total = events.count()
if paginate:
start = (page - 1) * page_size
end = start + page_size
page_qs = list(events[start:end])
else:
page_qs = list(events)
start, end = 0, total
event_ids = [e.id for e in page_qs]
primary_images = EventImages.objects.filter(event_id__in=event_ids, is_primary=True)
thumb_map = {img.event_id: img for img in primary_images}
events = Event.objects.all().order_by('-created_date')
event_list = []
for e in events:
data_dict = model_to_dict(e)
try:
thumb_img = EventImages.objects.get(event=e.id, is_primary=True)
data_dict['thumb_img'] = request.build_absolute_uri(thumb_img.event_image.url)
except EventImages.DoesNotExist:
data_dict['thumb_img'] = ''
event_list.append(data_dict)
print('*' * 100)
print(event_list)
print('*' * 100)
for e in page_qs:
d = model_to_dict(e)
img = thumb_map.get(e.id)
d['thumb_img'] = img.event_image.url if img else ''
event_list.append(d)
return JsonResponse({
"status": "success",
"events": event_list
"events": event_list,
"total": total,
"page": page,
"page_size": page_size,
"has_next": end < total,
})
except Exception as e:
return JsonResponse(
{"status": "error", "message": str(e)},
)
return JsonResponse({"status": "error", "message": str(e)})
class EventDetailAPI(APIView):
permission_classes = [AllowAny]
def post(self, request):
try:
user, token, data, error_response = validate_token_and_get_user(request)
if error_response:
return error_response
try:
data = json.loads(request.body) if request.body else {}
except Exception:
data = {}
event_id = data.get("event_id")
events = Event.objects.get(id=event_id)
event_images = EventImages.objects.filter(event=event_id)
event_data = model_to_dict(events)
@@ -110,18 +101,12 @@ class EventDetailAPI(APIView):
for ei in event_images:
event_img = {}
event_img['is_primary'] = ei.is_primary
event_img['image'] = request.build_absolute_uri(ei.event_image.url)
event_img['image'] = ei.event_image.url
event_images_list.append(event_img)
event_data["images"] = event_images_list
print(event_data)
return JsonResponse(event_data)
except Exception as e:
return JsonResponse(
{"status": "error", "message": str(e)},
)
return JsonResponse({"status": "error", "message": str(e)})
class EventImagesListAPI(APIView):
@@ -138,7 +123,7 @@ class EventImagesListAPI(APIView):
res_data["status"] = "success"
event_images_list = []
for ei in event_images:
event_images_list.append(request.build_absolute_uri(ei.event_image.url))
event_images_list.append(ei.event_image.url)
res_data["images"] = event_images_list
@@ -172,9 +157,7 @@ class EventsByCategoryAPI(APIView):
for event in events_dict:
try:
event['event_image'] = request.build_absolute_uri(
EventImages.objects.get(event=event['id'], is_primary=True).event_image.url
)
event['event_image'] = EventImages.objects.get(event=event['id'], is_primary=True).event_image.url
except EventImages.DoesNotExist:
event['event_image'] = ''
# event['start_date'] = convert_date_to_dd_mm_yyyy(event['start_date'])
@@ -352,7 +335,7 @@ class EventsByDateAPI(APIView):
data_dict = model_to_dict(e)
try:
thumb_img = EventImages.objects.get(event=e.id, is_primary=True)
data_dict['thumb_img'] = request.build_absolute_uri(thumb_img.event_image.url)
data_dict['thumb_img'] = thumb_img.event_image.url
except EventImages.DoesNotExist:
data_dict['thumb_img'] = ''
@@ -385,7 +368,7 @@ class FeaturedEventsAPI(APIView):
data_dict = model_to_dict(e)
try:
thumb = EventImages.objects.get(event=e.id, is_primary=True)
data_dict['thumb_img'] = request.build_absolute_uri(thumb.event_image.url)
data_dict['thumb_img'] = thumb.event_image.url
except EventImages.DoesNotExist:
data_dict['thumb_img'] = ''
event_list.append(data_dict)
@@ -411,7 +394,7 @@ class TopEventsAPI(APIView):
data_dict = model_to_dict(e)
try:
thumb = EventImages.objects.get(event=e.id, is_primary=True)
data_dict['thumb_img'] = request.build_absolute_uri(thumb.event_image.url)
data_dict['thumb_img'] = thumb.event_image.url
except EventImages.DoesNotExist:
data_dict['thumb_img'] = ''
event_list.append(data_dict)