mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 13:35:19 -05:00
feat: add public profiles list endpoint with search and pagination
- Add new /profiles/ endpoint for listing user profiles - Support search by username/display name with ordering options - Include pagination with configurable page size (max 100) - Add comprehensive OpenAPI schema documentation - Refactor passkey authentication state management in MFA flow - Update URL routing and imports for new list_profiles view This enables user discovery, leaderboards, and friend-finding features with a publicly accessible, well-documented API endpoint.
This commit is contained in:
@@ -823,6 +823,119 @@ def check_user_deletion_eligibility(request, user_id):
|
||||
)
|
||||
|
||||
|
||||
# === PUBLIC PROFILE LIST ENDPOINT ===
|
||||
|
||||
|
||||
@extend_schema(
|
||||
operation_id="list_profiles",
|
||||
summary="List user profiles with search and pagination",
|
||||
description=(
|
||||
"Returns a paginated list of public user profiles. "
|
||||
"Supports search by username or display name, and filtering by various criteria. "
|
||||
"This endpoint is used for user discovery, leaderboards, and friend finding."
|
||||
),
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
name="search",
|
||||
type=OpenApiTypes.STR,
|
||||
location=OpenApiParameter.QUERY,
|
||||
description="Search term for username or display name",
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="ordering",
|
||||
type=OpenApiTypes.STR,
|
||||
location=OpenApiParameter.QUERY,
|
||||
description="Order by field: date_joined, -date_joined, username, -username",
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="page",
|
||||
type=OpenApiTypes.INT,
|
||||
location=OpenApiParameter.QUERY,
|
||||
description="Page number for pagination",
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="page_size",
|
||||
type=OpenApiTypes.INT,
|
||||
location=OpenApiParameter.QUERY,
|
||||
description="Number of results per page (max 100)",
|
||||
),
|
||||
],
|
||||
responses={
|
||||
200: {
|
||||
"description": "Paginated list of public profiles",
|
||||
"example": {
|
||||
"count": 150,
|
||||
"next": "https://api.thrillwiki.com/api/v1/accounts/profiles/?page=2",
|
||||
"previous": None,
|
||||
"results": [
|
||||
{
|
||||
"user_id": "uuid-1",
|
||||
"username": "thrillseeker",
|
||||
"date_joined": "2024-01-01T00:00:00Z",
|
||||
"role": "USER",
|
||||
"profile": {
|
||||
"profile_id": "uuid-profile",
|
||||
"display_name": "Thrill Seeker",
|
||||
"avatar_url": "https://example.com/avatar.jpg",
|
||||
"bio": "Coaster enthusiast!",
|
||||
"total_credits": 150,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
tags=["User Profile"],
|
||||
)
|
||||
@api_view(["GET"])
|
||||
@permission_classes([AllowAny])
|
||||
def list_profiles(request):
|
||||
"""
|
||||
List public user profiles with search and pagination.
|
||||
|
||||
This endpoint provides the missing /accounts/profiles/ list endpoint
|
||||
that the frontend expects for user discovery features.
|
||||
"""
|
||||
from django.db.models import Q
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
|
||||
# Base queryset: only active users with public profiles
|
||||
queryset = User.objects.filter(
|
||||
is_active=True,
|
||||
).select_related("profile").order_by("-date_joined")
|
||||
|
||||
# Search filter
|
||||
search = request.query_params.get("search", "").strip()
|
||||
if search:
|
||||
queryset = queryset.filter(
|
||||
Q(username__icontains=search) |
|
||||
Q(profile__display_name__icontains=search)
|
||||
)
|
||||
|
||||
# Ordering
|
||||
ordering = request.query_params.get("ordering", "-date_joined")
|
||||
valid_orderings = ["date_joined", "-date_joined", "username", "-username"]
|
||||
if ordering in valid_orderings:
|
||||
queryset = queryset.order_by(ordering)
|
||||
|
||||
# Pagination
|
||||
class ProfilePagination(PageNumberPagination):
|
||||
page_size = 20
|
||||
page_size_query_param = "page_size"
|
||||
max_page_size = 100
|
||||
|
||||
paginator = ProfilePagination()
|
||||
page = paginator.paginate_queryset(queryset, request)
|
||||
|
||||
if page is not None:
|
||||
serializer = PublicUserSerializer(page, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
# Fallback if pagination fails
|
||||
serializer = PublicUserSerializer(queryset[:20], many=True)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
# === USER PROFILE ENDPOINTS ===
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user