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

如何用Django ORM获取含外键全量数据并返回JsonResponse

解决Django中select_related结合values()获取全量关联数据的问题

嘿,我完全懂你的困扰——手动把所有模型字段(包括关联外键的)一个个列在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:53:13