0

I'm trying to make a nested serializer with prefetch_related but it doesn't work, here's my code:

models.py

from django.db import models


class Student(models.Model):
    phone = models.IntegerField(null=True)
    birth_date = models.DateField(null=True)
    user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, related_name="student")


class Course(models.Model):
    title = models.CharField(max_length=100, blank=True, default='')


class CourseEnroll(models.Model):
    course = models.ForeignKey(Course, on_delete=models.PROTECT, related_name='course_enroll')
    student = models.ForeignKey(Student, on_delete=models.PROTECT, related_name='student_enroll')

views.py

from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet

from quiz.models import Course
from quiz.serializers import CourseSerializer


class CourseViewSet(mixins.CreateModelMixin,
                    mixins.ListModelMixin,
                    mixins.RetrieveModelMixin,
                    GenericViewSet):

    def get_queryset(self):
        queryset = Course.objects.prefetch_related("course_enroll").all()
        return queryset
    serializer_class = CourseSerializer

serializers.py

from rest_framework import serializers

from quiz.models import Course, CourseEnroll


class CourseEnrollSerializer(serializers.ModelSerializer):
    class Meta:
        model = CourseEnroll
        fields = ['id']


class CourseSerializer(serializers.ModelSerializer):
    student_enrolled = CourseEnrollSerializer(many=True, read_only=True)

    class Meta:
        model = Course
        fields = ['id', 'title', 'student_enrolled']

Here's my repo: https://github.com/congson95dev/regov-pop-quiz-backend-s-v1

Did I do something wrong here? Please help, thanks.

djvg
  • 11,722
  • 5
  • 72
  • 103
fudu
  • 617
  • 1
  • 10
  • 19

1 Answers1

1

prefetch_related does not create a nested serialization. Rather it is used to cache the related model fields, so that when the queryset is executed, it does not make additional DB calls.

Here, you are using student_entrolled pointing to CourseEnrollSerializer, which won't work because of wrong field name. It should be:

class CourseSerializer(serializers.ModelSerializer):
    course_enroll = CourseEnrollSerializer(many=True, read_only=True)

    class Meta:
        model = Course
        fields = ['id', 'title', 'course_enroll']
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • thanks for reply, you mean i should change from `student_entrolled` to `course_enroll` in serializers.py and it will be work? – fudu Apr 04 '23 at 15:03
  • Yes, just like you have defined in your model (using related_name) – ruddra Apr 04 '23 at 15:06
  • oh, so it should be the same name as `related_name` in model. – fudu Apr 04 '23 at 15:12
  • Yes, if not you can explicitly mention [`source`](https://www.django-rest-framework.org/api-guide/fields/#source) – ruddra Apr 04 '23 at 15:17
  • thanks, i'll check about this next morning. Also, can you pls help me on this one too? https://stackoverflow.com/questions/75930160/how-to-override-createsuperuser-command-in-django – fudu Apr 04 '23 at 15:43