如何通过Django REST Framework序列化多张无关表生成合并JSON输出
订单管理系统多类型订单统一序列化方案
问题背景
我正在开发一个订单管理系统,场景如下:用户可创建多种类型的订单,这些订单类型相互独立,但用户需要查看所有类型的订单。目前已在models.py中为每种订单类型创建了独立的数据表:
class OrderType1(models.Model): create_time = models.DateTimeField(auto_now_add=True, verbose_name="create_time") ordertype1_info = models.CharField(max_length=32, verbose_name="Exclusive info for OrderType1") class OrderType2(models.Model): create_time = models.DateTimeField(auto_now_add=True, verbose_name="create_time") ordertype2_info = models.CharField(max_length=32, verbose_name="Exclusive info for OrderType2") class OrderType3(models.Model): create_time = models.DateTimeField(auto_now_add=True, verbose_name="create_time") ordertype3_info = models.CharField(max_length=32, verbose_name="Exclusive info for OrderType3")
同时在serializers.py中对应创建了序列化器:
class OrderType1Serializer(serializers.ModelSerializer): class Meta: model = OrderType1 fields="__all__" class OrderType2Serializer(serializers.ModelSerializer): class Meta: model = OrderType2 fields="__all__" class OrderType3Serializer(serializers.ModelSerializer): class Meta: model = OrderType3 fields="__all__"
核心需求是:创建一个能返回所有类型订单的序列化逻辑,最终返回的JSON格式如下:
{ "OrderType1":[ { "id": 1, "create_time": "2018-01-01 12:00:00", "ordertype1_info": "Exclusive info for OrderType1" }, { "id": 2, "create_time": "2019-12-01 12:00:00", "ordertype1_info": "Exclusive info for OrderType1" } ], "OrderType2":[ { "id": 1, "create_time": "2020-01-01 12:00:00", "ordertype2_info": "Exclusive info for OrderType2" } ], "OrderType3":[ { "id": 1, "create_time": "2021-01-01 09:00:00", "ordertype3_info": "Exclusive info for OrderType3" }, { "id": 2, "create_time": "2022-12-01 10:00:00", "ordertype3_info": "Exclusive info for OrderType3" }, { "id": 3, "create_time": "2022-12-01 10:20:30", "ordertype3_info": "Exclusive info for OrderType3" } ] }
解决方案
由于DRF的ModelSerializer只能绑定单个模型,无法直接实现多模型的序列化,推荐以下两种实现方式:
方式一:视图层聚合数据(推荐)
直接在视图中查询各类型订单数据,用对应序列化器处理后组装成目标格式,代码简洁易维护:
# views.py from rest_framework.views import APIView from rest_framework.response import Response from .models import OrderType1, OrderType2, OrderType3 from .serializers import OrderType1Serializer, OrderType2Serializer, OrderType3Serializer # 定义订单类型与序列化器的映射,后续新增类型只需在此添加 ORDER_TYPE_MAPPING = [ (OrderType1, OrderType1Serializer, "OrderType1"), (OrderType2, OrderType2Serializer, "OrderType2"), (OrderType3, OrderType3Serializer, "OrderType3"), ] class AllOrdersView(APIView): def get(self, request): response_data = {} # 循环处理每种订单类型 for model, serializer_cls, key in ORDER_TYPE_MAPPING: queryset = model.objects.all() response_data[key] = serializer_cls(queryset, many=True).data return Response(response_data)
方式二:自定义序列化器
通过继承DRF的Serializer自定义一个统一序列化器,在to_representation方法中完成数据查询与组装:
# serializers.py from rest_framework import serializers from .models import OrderType1, OrderType2, OrderType3 from .serializers import OrderType1Serializer, OrderType2Serializer, OrderType3Serializer class AllOrdersSerializer(serializers.Serializer): def to_representation(self, instance): # 查询并序列化所有类型订单 order1_data = OrderType1Serializer(OrderType1.objects.all(), many=True).data order2_data = OrderType2Serializer(OrderType2.objects.all(), many=True).data order3_data = OrderType3Serializer(OrderType3.objects.all(), many=True).data return { "OrderType1": order1_data, "OrderType2": order2_data, "OrderType3": order3_data }
对应的视图实现:
# views.py from rest_framework.views import APIView from rest_framework.response import Response from .serializers import AllOrdersSerializer class AllOrdersView(APIView): def get(self, request): serializer = AllOrdersSerializer(instance=None) return Response(serializer.data)
补充说明
- 两种方式都能实现需求,方式一更灵活,后续新增订单类型只需修改
ORDER_TYPE_MAPPING列表即可,无需改动核心逻辑。 - 如果需要添加过滤、分页等功能,可在视图中对每个
queryset进行对应的处理后再序列化。
内容的提问来源于stack exchange,提问作者user277104
相关产品推荐
相关产品推荐

