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

Django Rest Framework双层嵌套序列化器问题

解决在ListingSerializer中获取所属Unit所有Price的问题

问题背景

你有三层关联的Django模型:Unit -> Listing -> Price,现在需要在Listing的序列化器里拿到当前Listing所属Unit下的所有Price(也就是该Unit下所有Listing的Price记录),之前用source="unit__listings__prices"的方式行不通,下面给两种可行的解决办法:


方法一:用SerializerMethodField自定义字段

这是最直接的实现方式,自己写方法来查询并序列化目标数据:

# serializers.py
class PriceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Price
        fields = ["amount"]

class ListingSerializer(serializers.ModelSerializer):
    # 自定义字段名,避免和当前Listing自己的prices混淆
    unit_all_prices = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Listing
        # 按需添加你需要的其他字段
        fields = ["number_of_bedrooms", "unit_all_prices"]

    def get_unit_all_prices(self, obj):
        # 通过当前Listing关联的Unit,筛选所有属于该Unit的Price
        all_prices = Price.objects.filter(listing__unit=obj.unit)
        return PriceSerializer(all_prices, many=True).data

方法二:预查询优化性能(避免N+1查询)

如果是在列表接口中使用上面的方法,会触发大量重复查询,建议在视图层提前预加载关联数据:

# views.py
from django.db.models import Prefetch
from rest_framework.viewsets import ReadOnlyModelViewSet
from .models import Listing, Price
from .serializers import ListingSerializer

class ListingViewSet(ReadOnlyModelViewSet):
    queryset = Listing.objects.select_related('unit').prefetch_related(
        # 预加载Unit下所有Listing的Price
        Prefetch('unit__listings__prices', queryset=Price.objects.all())
    )
    serializer_class = ListingSerializer

然后修改序列化器里的方法,直接从预加载的缓存里取数据,不用再发新查询:

# serializers.py
def get_unit_all_prices(self, obj):
    prices = []
    # 遍历Unit下的所有Listing,收集它们的Price
    for listing in obj.unit.listings.all():
        prices.extend(listing.prices.all())
    return PriceSerializer(prices, many=True).data

为什么原来的source写法无效?

DRF的source参数只能处理单层级的关联(不管是正向还是反向),没办法直接解析unit__listings__prices这种跨两层的一对多关联来返回集合数据,所以必须用自定义方法来处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:53:35