Django中外键多对一关系下嵌套数据获取方法咨询
Django多对一关系中获取嵌套关联数据的解决方案
首先先修正你代码里的一个小问题:Profesor模型的objects属性错用了AsigManager,应该改成ProfManager,否则会导致查询逻辑混乱:
class Profesor(models.Model): asignatura = models.ForeignKey(Asignatura, on_delete=models.CASCADE) Nombre = models.CharField(max_length=200) profesion = models.CharField(max_length=200) # 修正Manager引用 objects = ProfManager() class Meta: unique_together = [['Nombre', 'profesion']]
针对你需要返回嵌套Asignatura数据的需求,提供两种可行方案:
方案一:手动构造嵌套数据(无需额外依赖)
直接在视图中循环查询结果,手动将关联的Asignatura数据嵌套进返回字典,同时用select_related提前加载关联数据,避免多次查询数据库的N+1性能问题:
class ProfesorView(View): def get(self, request): # 提前加载关联的Asignatura,优化查询效率 profesores = Profesor.objects.select_related('asignatura').all() profe_list = [] for profe in profesores: # 构造包含嵌套数据的字典 profe_dict = { 'id': profe.id, 'Nombre': profe.Nombre, 'profesion': profe.profesion, 'asignatura': { 'id': profe.asignatura.id, 'Nom_Asig': profe.asignatura.Nom_Asig, 'horario': profe.asignatura.horario } } profe_list.append(profe_dict) if profe_list: datos = {'message':'Success','Profesores': profe_list} else: datos = {'message':'Profesor Not Found...'} return JsonResponse(datos)
方案二:使用Django REST Framework序列化器(推荐用于API开发)
如果你的项目是API服务,用DRF序列化器处理嵌套数据更简洁易维护:
- 先安装DRF(未安装的话):
pip install djangorestframework
- 在
settings.py中添加DRF到应用列表:
INSTALLED_APPS = [ # ...其他已有应用 'rest_framework', ]
- 定义序列化器:
from rest_framework import serializers class AsignaturaSerializer(serializers.ModelSerializer): class Meta: model = Asignatura fields = ['id', 'Nom_Asig', 'horario'] class ProfesorSerializer(serializers.ModelSerializer): # 嵌套关联的Asignatura序列化器,自动处理数据关联 asignatura = AsignaturaSerializer() class Meta: model = Profesor fields = ['id', 'Nombre', 'profesion', 'asignatura']
- 修改视图为DRF的APIView:
from rest_framework.views import APIView from rest_framework.response import Response class ProfesorView(APIView): def get(self, request): profesores = Profesor.objects.select_related('asignatura').all() serializer = ProfesorSerializer(profesores, many=True) if serializer.data: return Response({'message':'Success','Profesores': serializer.data}) else: return Response({'message':'Profesor Not Found...'}, status=404)
两种方案都能实现嵌套数据返回,方案一适合快速修改现有代码,方案二更适合长期维护的API项目。
内容的提问来源于stack exchange,提问作者Ivan Andres Serna
相关产品推荐
相关产品推荐

