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

如何在Django中获取min_price对应的Price关联数据并序列化展示?

解决方法:获取对应最低价格的Price对象数据

你遇到的问题有两个核心原因:一是之前的prefetch_related只是预取了该手机的所有Price记录,而非对应最低价格的那条;二是自定义序列化字段sdata没有被包含在输出里(因为你用了fields='__all__',它只会包含模型本身的字段,不会自动包含自定义嵌套字段)。

下面是完整的分步解决方案:

第一步:修改QuerySet,精准筛选对应最低价格的Price记录

我们需要用Subquery和Prefetch来定位每个手机对应的最低价格记录,而非预取所有价格数据。在你的views.py中修改如下:

from django.db.models import Subquery, OuterRef, Min
from django.db.models.query import Prefetch
from rest_framework import generics

class PhoneAPI(generics.ListAPIView):
    serializer_class = PhoneSerializer

    def get_queryset(self):
        # 子查询1:获取每个手机的最低价格数值
        min_price_subquery = Price.objects.filter(
            phone=OuterRef('pk')
        ).values('phone').annotate(min_p=Min('price')).values('min_p')
        
        # 子查询2:筛选出对应最低价格的Price完整记录
        lowest_price_queryset = Price.objects.filter(
            phone=OuterRef('pk'),
            price=Subquery(min_price_subquery[:1])
        )
        
        # 给Phone对象预取筛选后的最低价格记录,存入自定义属性lowest_price_obj
        return Phone.objects.annotate(
            min_price=Min('price__price')
        ).prefetch_related(
            Prefetch(
                'price_set',
                queryset=lowest_price_queryset,
                to_attr='lowest_price_obj'
            )
        )

第二步:修改序列化器,展示关联的Price数据

现在需要在PhoneSerializer中添加字段,序列化我们预取的lowest_price_obj,同时注意显式列出所有需要的字段(不要用fields='__all__'):

from rest_framework import serializers
from .models import Phone, Price

class PriceSerializer(serializers.ModelSerializer):
    phone = serializers.StringRelatedField()
    market = serializers.StringRelatedField()

    class Meta:
        model = Price
        fields = ('id', 'price', 'date', 'market', 'phone')

class PhoneSerializer(serializers.ModelSerializer):
    min_price = serializers.IntegerField()
    # 序列化预取的最低价格对象,many=False表示单个记录(若有多个相同最低价可改为True)
    lowest_price = PriceSerializer(source='lowest_price_obj', many=False, read_only=True)

    class Meta:
        model = Phone
        # 显式列出所有需要返回的字段,包括自定义的lowest_price
        fields = ['id', 'min_price', 'name', 'description', 'image', 'slug_phone', 'lowest_price']

最终效果

修改完成后,你的API输出会新增lowest_price字段,里面包含对应最低价格的date、market等完整Price数据,示例输出如下:

{"count":7,"next":null,"previous":null,"results":[
    {"id":10,"min_price":718,"name":"SAMSUNG Galaxy S10",
     "description":"SAMSUNG Galaxy S10, Smartphone, 128 GB, Prism Black, Dual SIM",
     "image":"http://127.0.0.1:8000/media/phone_img/galaxy_s10.jpg",
     "slug_phone":"samsung-galaxy-s10",
     "lowest_price":{
         "id":5,
         "price":"718.00",
         "date":"2024-05-20",
         "market":"某电商平台",
         "phone":"SAMSUNG Galaxy S10"
     }
    },
    ...
]}

如果某款手机存在多条价格相同的最低记录,只需把PhoneSerializer中的many=False改为many=True,即可返回所有符合条件的Price记录列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:37:38