From 0404a369188a9392e21b3431077466c0419fa63c Mon Sep 17 00:00:00 2001 From: sandronadiradze Date: Sat, 2 Nov 2024 07:27:52 +0400 Subject: [PATCH] chore: start using more efficient queries for auction retrieve view --- auction/serializers.py | 15 +++++++-------- auction/views.py | 43 +++++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/auction/serializers.py b/auction/serializers.py index c193a77..8da285e 100644 --- a/auction/serializers.py +++ b/auction/serializers.py @@ -143,15 +143,14 @@ def get_category(self, obj): def get_statistics(self, obj): if obj.status == StatusChoices.DRAFT: return None - auction_statistics = AuctionStatistics.objects.filter(auction=obj.id).first() return { - "winner_bid": auction_statistics.winner_bid, - "winner_bid_author": auction_statistics.winner_bid_author, - "top_bid": auction_statistics.top_bid, - "top_bid_author": auction_statistics.top_bid_author, - "views_count": auction_statistics.views_count, - "total_bids_count": auction_statistics.total_bids_count, - "bookmarks_count": auction_statistics.bookmarks_count, + "winner_bid": obj.statistics.winner_bid, + "winner_bid_author": obj.statistics.winner_bid_author, + "top_bid": obj.statistics.top_bid, + "top_bid_author": obj.statistics.top_bid_author, + "views_count": obj.statistics.views_count, + "total_bids_count": obj.statistics.total_bids_count, + "bookmarks_count": obj.statistics.bookmarks_count, } def to_representation(self, instance): diff --git a/auction/views.py b/auction/views.py index e38f67b..5fa31d9 100755 --- a/auction/views.py +++ b/auction/views.py @@ -477,21 +477,30 @@ def get_object(self): user_is_seller = self.request.user.is_seller try: - # Base query with bookmark annotation - base_query = Auction.objects.annotate( - bookmark_id=Subquery( - Bookmark.objects.filter( - user_id=user_id, auction_id=OuterRef("pk") - ).values("id")[:1] - ), - bookmarked=Case( - When(bookmark_id__isnull=False, then=True), - default=False, - output_field=BooleanField(), - ), + # Base query with all necessary relations and annotations + base_query = ( + Auction.objects.select_related( + "statistics", + "category", + ) + .prefetch_related( + "tags", + ) + .annotate( + bookmark_id=Subquery( + Bookmark.objects.filter( + user_id=user_id, auction_id=OuterRef("pk") + ).values("id")[:1] + ), + bookmarked=Case( + When(bookmark_id__isnull=False, then=True), + default=False, + output_field=BooleanField(), + ), + ) ) - # bid-related annotations only for users with user_type of Seller + # bid-related annotations only for sellers if user_is_seller: base_query = base_query.annotate( has_bid=Exists( @@ -499,13 +508,13 @@ def get_object(self): ), ) - # Getting the auction with appropriate/combined annotations + # Get the auction with a single query auction = base_query.get(id=self.kwargs["id"]) # Increment views count for the auction - AuctionStatistics.objects.filter(auction=auction.id).update( - views_count=F("views_count") + 1 - ) + auction.statistics.views_count = F("views_count") + 1 + auction.statistics.save(update_fields=["views_count"]) + auction.statistics.refresh_from_db() # Handle draft auction access based on user permissions if auction.status == StatusChoices.DRAFT: