Django多对多关联报错:QuerySet无法JSON序列化,求解决方案
问题解决:Object of type QuerySet is not JSON serializable
错误原因
你在order_list视图手动构造订单数据时,products字段直接传入了order.products.all()——这是一个QuerySet对象,Python的JSON序列化器无法直接处理该类型,因此抛出序列化错误。另外你还存在两个小问题:一是orders = Orders.objects.select_related('supply').all少了括号,实际拿到的是方法引用而非查询结果;二是直接调用order.products.all()无法获取关联表OrderProduct中的product_quantity字段。
解决方案一:使用已定义的Serializer(推荐)
你已经编写了序列化器,直接用它处理多对多关联的嵌套序列化更规范:
1. 修正serializers.py
class OrderProductSerializer(serializers.ModelSerializer): product = ProductSerializer() class Meta: model = OrderProduct fields = ['product', 'product_quantity'] # 关联产品+数量字段 class OrderSerializer(serializers.ModelSerializer): supply = SupplySerializer() # 多对多通过中间表关联,指定source为中间表的反向关联名 products = OrderProductSerializer(many=True, source='orderproduct_set') class Meta: model=Orders fields=('order_id', 'order_number', 'date_of_order', 'statut', 'supply', 'products')
2. 修改views.py
from django.http import JsonResponse from .serializers import OrderSerializer from .models import Orders from django.views.decorators.csrf import csrf_exempt @csrf_exempt def order_list(request): # 用prefetch_related预加载中间表数据,避免N+1查询 orders = Orders.objects.select_related('supply').prefetch_related('orderproduct_set').all() serializer = OrderSerializer(orders, many=True) return JsonResponse(serializer.data, safe=False)
解决方案二:手动构造可序列化数据
如果不想用Serializer,需将QuerySet转为字典列表,同时获取中间表的数量字段:
@csrf_exempt def order_list(request): orders = Orders.objects.select_related('supply').all() order_list = [] for order in orders: # 遍历中间表获取产品+数量 product_items = [] for op in order.orderproduct_set.all(): product_items.append({ 'product_id': op.product.product_id, 'product_name': op.product.product_name, 'product_quantity': op.product_quantity }) order_list.append({ 'order_id': order.order_id, 'order_number': order.order_number, 'date_of_order': order.date_of_order, 'supply_id': order.supply.supply_id, 'supply_name': order.supply.supply_name, 'supply_address': order.supply.supply_address, 'products': product_items }) return JsonResponse(order_list, safe=False)
内容的提问来源于stack exchange,提问作者Derick T.
相关产品推荐
相关产品推荐

