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

如何在Django REST Framework中将嵌套序列化数据转为单列表对象

Django REST Framework 实现嵌套数据扁平列表返回

当前代码采用嵌套序列化结构,返回国家包含州、州包含城市的层级数据,无法满足将每个(国家-州-城市)或(国家-州)组合作为独立条目返回的需求,以下是具体解决方案:

1. 修正模型笔误

先修复模型中的两处错误,避免后续运行报错:

class Country(models.Model):
    country_id = models.IntegerField(primary_key=True)
    cname = models.CharField(max_length=100)
    
    def __str__(self):
        return self.cname  # 原代码误写为self.name,改为对应字段cname

class City(models.Model):
    cityid= models.IntegerField(primary_key=True)
    city_name = models.CharField(max_length=100)
    city_strength = models.IntegerField()
    city_state = models.ForeignKey(State, related_name='cstate', on_delete=models.CASCADE)
    
    def __str__(self):
        return self.city_name  # 原代码误写为self.sname,改为对应字段city_name

2. 定义扁平结构序列化器

不需要嵌套序列化器,直接创建包含所有所需字段的序列化器,允许城市相关字段为null(适配无城市的州):

from rest_framework import serializers
from .models import Country, State, City

class FlatLocationSerializer(serializers.Serializer):
    country_id = serializers.IntegerField()
    cname = serializers.CharField(max_length=100)
    stateid = serializers.IntegerField()
    state_name = serializers.CharField(max_length=100)
    cityid = serializers.IntegerField(allow_null=True)
    city_name = serializers.CharField(max_length=100, allow_null=True)
    city_strength = serializers.IntegerField(allow_null=True)

3. 调整视图生成扁平数据

在视图中根据国家ID获取关联数据,将每个关联组合转换为独立条目:

from rest_framework import generics, Response
from django.db.models import Prefetch
from .models import Country, State, City
from .serializers import FlatLocationSerializer

class FilterStateCityView(generics.ListAPIView):
    serializer_class = FlatLocationSerializer

    def get_queryset(self):
        # 从URL参数获取国家ID,示例请求URL:/locations/?country_id=23
        country_id = self.request.query_params.get('country_id')
        if not country_id:
            return []
        
        try:
            # 预关联数据避免N+1查询问题
            country = Country.objects.prefetch_related(
                Prefetch('scountry', queryset=State.objects.prefetch_related('cstate'))
            ).get(country_id=country_id)
        except Country.DoesNotExist:
            return []
        
        flat_data = []
        # 遍历国家下的所有州
        for state in country.scountry.all():
            cities = state.cstate.all()
            if cities.exists():
                # 每个城市生成一条独立记录
                for city in cities:
                    flat_data.append({
                        'country_id': country.country_id,
                        'cname': country.cname,
                        'stateid': state.stateid,
                        'state_name': state.state_name,
                        'cityid': city.cityid,
                        'city_name': city.city_name,
                        'city_strength': city.city_strength
                    })
            else:
                # 无城市的州单独生成一条记录
                flat_data.append({
                    'country_id': country.country_id,
                    'cname': country.cname,
                    'stateid': state.stateid,
                    'state_name': state.state_name,
                    'cityid': None,
                    'city_name': None,
                    'city_strength': None
                })
        return flat_data

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

预期响应示例

请求/locations/?country_id=23后,返回的响应格式如下:

[ 
 { 
  "country_id":23,
  "cname": "USA",
  "stateid": 16,
  "state_name": "Florida",
  "cityid":55,
  "city_name": "Miami",
  "city_strength": 40005
 },
 { 
  "country_id":23,
  "cname": "USA",
  "stateid": 16,
  "state_name": "Florida",
  "cityid":56,
  "city_name": "Orlando",
  "city_strength": 930067
 },
 {
  "country_id":23,
  "cname": "USA",
  "stateid": 17,
  "state_name": "Texas",
  "cityid": null,
  "city_name": null,
  "city_strength": null
 }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 15:55:18