如何用Django ORM获取含外键全量数据并返回JsonResponse
嘿,我完全懂你的困扰——手动把所有模型字段(包括关联外键的)一个个列在values()里太麻烦了,而且values('__all__')只返回当前模型的字段,关联模型的根本拿不到。我给你分享几个实用的解决方案,按需选用:
方案1:用Django REST Framework的Serializer(最推荐)
这是最优雅且易维护的方式,Serializer会自动帮你处理嵌套关联,不用手动写任何字段名。
首先定义对应的序列化器:
from rest_framework import serializers from .models import Order, PersoanaFizica, PersoanaJuridica class PersoanaJuridicaSerializer(serializers.ModelSerializer): class Meta: model = PersoanaJuridica fields = '__all__' # 或者指定你需要的字段列表 class PersoanaFizicaSerializer(serializers.ModelSerializer): # 嵌套关联的序列化器 persoana_juridica = PersoanaJuridicaSerializer() class Meta: model = PersoanaFizica fields = '__all__' class OrderSerializer(serializers.ModelSerializer): persoana_fizica = PersoanaFizicaSerializer() class Meta: model = Order fields = '__all__'
然后在视图里使用:
from django.http import JsonResponse def get_orders(request): # 用select_related提前加载关联数据,避免N+1查询 orders = Order.objects.select_related('persoana_fizica__persoana_juridica').all() # 序列化数据,many=True表示处理多个对象 serialized_data = OrderSerializer(orders, many=True).data return JsonResponse(serialized_data, safe=False)
这个方案的好处是:后续模型字段变更时,序列化器会自动同步,不用手动修改字段列表;还能灵活控制返回哪些字段(把__all__换成具体字段名列表即可),返回的是嵌套结构的JSON,可读性更好。
方案2:动态生成字段列表给values()用
如果不想引入DRF,咱们可以通过模型的_meta属性自动获取所有字段名,给关联字段加上前缀,再传给values():
from django.http import JsonResponse from .models import Order, PersoanaFizica, PersoanaJuridica def get_orders(request): # 获取Order模型的所有字段名 order_fields = [field.name for field in Order._meta.fields] # 获取PersoanaFizica的字段名,加上关联前缀 pf_fields = [f'persoana_fizica__{field.name}' for field in PersoanaFizica._meta.fields] # 获取PersoanaJuridica的字段名,加上多级关联前缀 pj_fields = [f'persoana_fizica__persoana_juridica__{field.name}' for field in PersoanaJuridica._meta.fields] # 合并所有字段 all_fields = order_fields + pf_fields + pj_fields # 查询并返回数据 orders = Order.objects.select_related('persoana_fizica__persoana_juridica').values(*all_fields) return JsonResponse(list(orders), safe=False)
注意:这个方法返回的是扁平结构的JSON,比如persoana_fizica__nume这样的键,而不是嵌套对象。如果需要嵌套结构,这个方案就不太合适了。
方案3:手动遍历构建嵌套字典
纯Django原生实现,不用任何额外库,适合小项目或者不想引入DRF的场景:
from django.http import JsonResponse from .models import Order def get_orders(request): orders = Order.objects.select_related('persoana_fizica__persoana_juridica').all() result = [] for order in orders: # 构建Order自身的字段字典 order_dict = {field.name: getattr(order, field.name) for field in Order._meta.fields} # 构建PersoanaFizica的字段字典 pf = order.persoana_fizica pf_dict = {field.name: getattr(pf, field.name) for field in pf._meta.fields} # 构建PersoanaJuridica的字段字典并嵌套进去 pj = pf.persoana_juridica pf_dict['persoana_juridica'] = {field.name: getattr(pj, field.name) for field in pj._meta.fields} # 把关联数据嵌套到Order字典里 order_dict['persoana_fizica'] = pf_dict result.append(order_dict) return JsonResponse(result, safe=False)
这个方法能生成嵌套结构的JSON,但缺点是如果模型字段有变更,你需要同步修改这段代码,维护成本比Serializer高一些。
内容的提问来源于stack exchange,提问作者Viorel Andrei Chis
相关产品推荐
相关产品推荐

