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

Django 2.0+DRF3.8.0下GET接口JSON嵌套格式改造求助

搞定DRF返回嵌套JSON数组的问题

嘿,我来帮你解决这个DRF序列化的问题!你现在用的是Django 2.0 + DRF 3.8.0,想要让GET接口返回嵌套的JSON数组结构,但目前只能拿到平级的列表,对吧?

首先得明确下你期望的目标嵌套格式大概是什么样的?比如是不是类似这样:

{
  "student": {
    "id": 1,
    "name": "张三"
  },
  "lectures": [
    {
      "id": 1,
      "title": "数学导论"
    },
    {
      "id": 2,
      "title": "计算机基础"
    }
  ]
}

而不是现在返回的[ {"id":1, ...}, {"id":2, ...} ]这种普通数组?

我先基于常见的模型结构给你解决方案,要是你的实际代码和我假设的不一样,随时调整就行:

1. 先假设你的模型结构(如果不符,替换成你的实际代码)

一般这种场景的模型大概是这样:

from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=100)
    # 其他字段比如学号、年级之类的...

class Lecture(models.Model):
    title = models.CharField(max_length=200)
    teacher = models.CharField(max_length=100)
    # 其他字段比如上课时间...

class StudentLecture(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='enrolled_lectures')
    lecture = models.ForeignKey(Lecture, on_delete=models.CASCADE)
    enroll_date = models.DateTimeField(auto_now_add=True)

2. 调整序列化器,实现嵌套结构

要生成嵌套JSON,得用嵌套序列化器或者SerializerMethodField来关联关联数据。这里分两种常见情况:

情况一:返回某个学生的所有选课信息(学生为主体,嵌套课程列表)

from rest_framework import serializers
from .models import Student, Lecture, StudentLecture

# 先定义课程的基础序列化器
class LectureSerializer(serializers.ModelSerializer):
    class Meta:
        model = Lecture
        fields = ('id', 'title', 'teacher')  # 选你需要返回的字段

# 定义学生的嵌套序列化器,包含其选课列表
class StudentWithLecturesSerializer(serializers.ModelSerializer):
    # 用SerializerMethodField来获取该学生的所有课程
    lectures = serializers.SerializerMethodField()

    def get_lectures(self, student_obj):
        # 通过Student的related_name拿到关联的StudentLecture,再取出对应的Lecture
        enrolled_lectures = student_obj.enrolled_lectures.all()
        return LectureSerializer([sl.lecture for sl in enrolled_lectures], many=True).data

    class Meta:
        model = Student
        fields = ('id', 'name', 'lectures')  # 包含嵌套的lectures字段

情况二:返回单个选课记录,嵌套学生和课程的详情

如果你的接口是想返回某条StudentLecture记录,同时包含对应的学生和课程的完整信息,那序列化器可以这么写:

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ('id', 'name')

class LectureSerializer(serializers.ModelSerializer):
    class Meta:
        model = Lecture
        fields = ('id', 'title', 'teacher')

class StudentLectureNestedSerializer(serializers.ModelSerializer):
    # 直接嵌套学生和课程的序列化器
    student = StudentSerializer()
    lecture = LectureSerializer()

    class Meta:
        model = StudentLecture
        fields = ('id', 'student', 'lecture', 'enroll_date')

3. 修改视图逻辑,返回嵌套结构而非平级列表

你的接口路径是/studentlectures/1/get_studlect/,这里的pk=1如果是学生ID,那视图可以这么写:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import NotFound
from .models import Student
from .serializers import StudentWithLecturesSerializer

class StudentLectureDetailView(APIView):
    def get(self, request, pk):
        try:
            student = Student.objects.get(pk=pk)
        except Student.DoesNotExist:
            raise NotFound(detail="学生不存在")
        
        serializer = StudentWithLecturesSerializer(student)
        return Response(serializer.data)

如果pk=1是StudentLecture的ID,那视图调整为:

from .models import StudentLecture
from .serializers import StudentLectureNestedSerializer

class StudentLectureDetailView(APIView):
    def get(self, request, pk):
        try:
            stud_lect = StudentLecture.objects.get(pk=pk)
        except StudentLecture.DoesNotExist:
            raise NotFound(detail="选课记录不存在")
        
        serializer = StudentLectureNestedSerializer(stud_lect)
        return Response(serializer.data)

4. 验证返回结果

调整后,情况一的接口会返回:

{
  "id": 1,
  "name": "张三",
  "lectures": [
    {
      "id": 1,
      "title": "数学导论",
      "teacher": "李老师"
    },
    {
      "id": 2,
      "title": "计算机基础",
      "teacher": "王老师"
    }
  ]
}

情况二的接口会返回:

{
  "id": 1,
  "student": {
    "id": 1,
    "name": "张三"
  },
  "lecture": {
    "id": 1,
    "title": "数学导论",
    "teacher": "李老师"
  },
  "enroll_date": "2024-05-20T14:30:00Z"
}

如果你的实际模型或者期望的嵌套格式和上面不一样,把你的模型、序列化器、视图代码贴出来,我再帮你精准修改!


内容的提问来源于stack exchange,提问作者RaphaelDP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:27:24