You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF获取count值最高的2条Product记录问题求助

Fixing the Top Viewed Products API in DRF

Hey there! Let's fix your code step by step. The main issue with your original approach is that aggregate(Max('count')) only returns the highest count value (as a dictionary like {'count__max': X}), not the product IDs associated with the top view counts. Here's the corrected implementation:

Corrected View Code

from django.db.models import Case, When
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Product, ProductViewCount
from .serializers import ProductSerializer  # Ensure this is imported correctly

class ViewTopLiked(APIView):
    def get(self, request):
        # Get top 2 ProductViewCount records ordered by highest count first
        top_view_entries = ProductViewCount.objects.order_by('-count')[:2]
        
        # Extract product IDs in the order of highest view count
        prod_ids = list(top_view_entries.values_list('product', flat=True))
        
        # Fetch Product records while preserving the view count ranking order
        if prod_ids:
            # Use Case/When to maintain the order of our prod_ids list
            ordering = Case(*[When(product_id=prod_id, then=index) for index, prod_id in enumerate(prod_ids)])
            products = Product.objects.filter(product_id__in=prod_ids).order_by(ordering)
        else:
            # Handle empty ProductViewCount scenario gracefully
            products = Product.objects.none()
        
        # Serialize and return the response
        serializer = ProductSerializer(instance=products, many=True, context={'request': request})
        return Response(serializer.data)

Key Changes Explained

  1. Replacing aggregate with ordered queryset:

    • Instead of aggregate(Max('count')), we use ProductViewCount.objects.order_by('-count')[:2] to fetch the top 2 records with the highest view counts, sorted in descending order.
  2. Extracting product IDs:

    • values_list('product', flat=True) on the ordered queryset gives us a flat list of associated product IDs. Converting to a list ensures we keep the ranking order for the next step.
  3. Preserving ranking order in Product results:

    • Django's default filter(product_id__in=...) doesn't maintain the input list order. Using Case and When ensures products are returned in the same order as their view count ranking (most viewed first).
  4. Edge case handling:

    • We added a check for empty prod_ids to avoid errors when there are no records in ProductViewCount.

Additional Notes

  • If multiple products have the same highest count, the queryset will take the first two entries based on Django's default ordering (primary key). To add a tiebreaker (e.g., newest products first), adjust the order_by clause:
    top_view_entries = ProductViewCount.objects.order_by('-count', '-product__created_date')[:2]
    
  • Double-check that your ProductSerializer includes all the fields you need from the Product model.

内容的提问来源于stack exchange,提问作者devmrh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:37:16