首页 > 解决方案 > Django REST 多嵌套序列化器过滤器

问题描述

有没有办法过滤多个嵌套的序列化器?

我有一个显示所有学生课程的学生序列化程序。课程显示所有作业及其分数。我想设计后端的方式是每个学生都会收到相同的作业大纲,但只有分数会发生变化;因此,为了减少重复数据,我创建了指向作业和学生的分数表。

但是,当我执行 GET 请求时,它会获取该作业实例的所有学生分数。有没有办法过滤它以只获得特定学生的分数?我为这个例子简化了我的模型,但问题本质上是一样的。

在我的回复中,您可以看到“score”:1 和“score”:2,它们属于两个不同的学生,但我想获得与特定学生相关的特定分数。

楷模

class Student(models.Model):
    firstName = models.CharField(max_length=20)
    age = models.IntegerField(default=18)

    def __str__(self):
        return self.firstName


class Course(models.Model):
    courseName = models.CharField(max_length=20)
    courseYear = models.IntegerField(default=2021)
    student = models.ManyToManyField(Student, related_name='courses')

    def __str__(self):
        return self.courseName + " " + str(self.courseYear)


class Homework(models.Model):
    hwName = models.CharField(max_length=20)
    hwPossScore = models.IntegerField(default=100)
    course = models.ForeignKey(
        Course, related_name='homeworks', on_delete=models.CASCADE, null=True, blank=True)
    students = models.ManyToManyField(Student)

    def __str__(self):
        return self.hwName


class Score(models.Model):
    student = models.ForeignKey(
        Student, related_name='studentScore', on_delete=models.CASCADE, null=True, blank=True)
    homework = models.ForeignKey(
        Homework, related_name='studentScore', on_delete=models.CASCADE, null=True, blank=True)
    score = models.IntegerField(default=0)

    def __str__(self):
        return self.student.firstName + " " + str(self.score)

序列化器

class ScoreSerializer(serializers.ModelSerializer):
    class Meta:
        model = Score
        fields = ['score', ]


class HomeworkSerializer(serializers.ModelSerializer):
    studentScore = ScoreSerializer(many=True)

    class Meta:
        model = Homework
        fields = ['hwName', 'hwPossScore', 'studentScore', ]


class CourseSerializer(serializers.ModelSerializer):
    homeworks = HomeworkSerializer(many=True)

    class Meta:
        model = Course
        fields = "__all__"


class StudentSerializer(serializers.ModelSerializer):
    courses = CourseSerializer(many=True)

    class Meta:
        model = Student
        fields = "__all__"

意见

class StudentView(APIView):

    permission_classes = [permissions.IsAuthenticated, ]

    def get_object(self, request):
        try:
            requestToken = request.META['HTTP_AUTHORIZATION'].split(' ')[1]
            userObj = Token.objects.get(key=requestToken).user
            studentObj = Student.objects.filter(user=userObj)[0]

            # If requester token does not match user return permission denied
            if(self.request.user != userObj):
                raise PermissionDenied()

            return studentObj
        except Student.DoesNotExist:
            raise Http404

    def get(self, request, format=None):

        # Create a field variable for all Board objects that count the number of topics for each board
        student = self.get_object(request)
        serializer = StudentSerializer(student)
        return Response(serializer.data)

回复

{
    "id": 1,
    "courses": [
        {
            "id": 1,
            "homeworks": [
                {
                    "hwName": "HW1",
                    "hwPossScore": 100,
                    "studentScore": [
                        {
                            "score": 1
                        },
                        {
                            "score": 2
                        }
                    ]
                }
            ],
            "courseName": "MATH 101",
            "courseYear": 2021,
            "student": [
                1
            ]
        }
    ],
    "firstName": "Red",
    "age": 18
}

标签: djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-serializer

解决方案


我认为您可以使用 ScoreSerializer 代替 StudentSerializer。在 ScoreSerializer 中,那个类继承 ModelSerializer 可以使用 field = ' all ',因为在 ScoreModel 中有 student、score 和 homeworks 字段。


推荐阅读