Nested Serializer for prefect_related in Django Rest Framework
Question:
I’m trying to make a nested serializer with prefect_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.
Answers:
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']
I’m trying to make a nested serializer with prefect_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.
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']