Skip to content

Commit

Permalink
chore: modify buyer leaderboard to return only the users data and top…
Browse files Browse the repository at this point in the history
… 50 buyers
  • Loading branch information
sandronadiradze committed Nov 5, 2024
1 parent fb817dc commit b25453f
Showing 1 changed file with 58 additions and 77 deletions.
135 changes: 58 additions & 77 deletions auction/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
OuterRef,
Subquery,
When,
Window,
)
from django.db.models.functions import Greatest, RowNumber
from django.db.models.functions import Greatest
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -1505,104 +1504,86 @@ def post(self, request, auction_id, *args, **kwargs):
)
class BuyerLeaderBoardStatisticsListView(generics.ListAPIView):
permission_classes = [IsAuthenticated, IsBuyer]
pagination_class = None

def get_queryset(self):
def get_top_50_queryset(self):
return (
Auction.objects.filter(
status=StatusChoices.COMPLETED,
statistics__winner_bid_object__isnull=False,
)
.values(
"author",
"author_nickname",
"author_avatar",
)
.annotate(
completed_auctions_count=Count("id"),
rank=Window(
expression=RowNumber(), order_by=F("completed_auctions_count").desc()
),
.values("author", "author_nickname", "author_avatar")
.annotate(completed_auctions_count=Count("id"))
.order_by("-completed_auctions_count")[:50]
)

def get_user_stats(self, request):
user_id = request.user.id
completed_with_winner = Auction.objects.filter(
author=user_id,
status=StatusChoices.COMPLETED,
statistics__winner_bid_object__isnull=False,
)

# Rank all users with completed auctions with winning bids
all_users_ranked = (
Auction.objects.filter(
status=StatusChoices.COMPLETED,
statistics__winner_bid_object__isnull=False,
)
.order_by("-completed_auctions_count")
.values("author")
.annotate(completed_count=Count("id"))
.order_by("-completed_count")
)

# Find user's rank in all users
user_rank = None
completed_count = completed_with_winner.count()
for idx, entry in enumerate(all_users_ranked, start=1):
if str(user_id) == str(entry["author"]):
user_rank = idx
break

return {
"author": user_id,
"author_nickname": getattr(request.user, "nickname", None),
"author_avatar": getattr(request.user, "avatar", None),
"completed_auctions_count": completed_count,
"rank": user_rank,
}

def format_users(self, users):
return [
{
"rank": user["rank"],
"rank": idx + 1, # Set rank based on position in top 50 list
"author_id": user["author"],
"author_nickname": user["author_nickname"],
"author_avatar": user["author_avatar"],
"completed_auctions_count": user["completed_auctions_count"],
}
for user in users
for idx, user in enumerate(users)
]

def list(self, request, *args, **kwargs):
requesting_user_id = request.user.id
# Get top 50 users
top_50_users = list(self.get_top_50_queryset())

# Get the complete ordered queryset and materialize it
complete_queryset = list(self.get_queryset())
# Get requesting user's stats
user_data = self.get_user_stats(request)

# Get top 3 users
top_three = complete_queryset[:3]

# Get paginated results
page = self.paginate_queryset(complete_queryset)
formatted_users = self.format_users(page)

# Find user's data in the complete queryset
user_data = None
for item in complete_queryset:
if str(item["author"]) == str(
requesting_user_id
): # Convert both to strings to ensure matching
user_data = item
break

# If user not found in complete_queryset but exists in results, use that data
if not user_data:
for item in formatted_users:
if str(item["author_id"]) == str(requesting_user_id):
user_data = {
"rank": item["rank"],
"author": item["author_id"],
"author_nickname": item["author_nickname"],
"author_avatar": item["author_avatar"],
"completed_auctions_count": item["completed_auctions_count"],
}
break

if user_data:
user_data_response = {
"rank": user_data["rank"],
"author_id": user_data["author"],
"author_nickname": user_data["author_nickname"],
"author_avatar": user_data["author_avatar"],
"completed_auctions_count": user_data["completed_auctions_count"],
}
else:
user_data_response = {
"rank": None,
"author_id": requesting_user_id,
"author_nickname": (
request.user.nickname if hasattr(request.user, "nickname") else None
),
"author_avatar": (
request.user.avatar if hasattr(request.user, "avatar") else None
),
"completed_auctions_count": 0,
}
user_data_response = {
"rank": (
user_data["rank"] if user_data["completed_auctions_count"] > 0 else None
),
"author_id": user_data["author"],
"author_nickname": user_data["author_nickname"],
"author_avatar": user_data["author_avatar"],
"completed_auctions_count": user_data["completed_auctions_count"],
}

paginated_response = {
response_data = {
"user_data": user_data_response,
"top_three_users": self.format_users(top_three),
"results": formatted_users,
"results": self.format_users(top_50_users),
}

response = self.get_paginated_response(paginated_response)
response.data["user_data"] = paginated_response["user_data"]
response.data["top_three_users"] = paginated_response["top_three_users"]
response.data["results"] = paginated_response["results"]

return response
return Response(response_data)

0 comments on commit b25453f

Please sign in to comment.