I have the below serializer.py file. I have validate_semester() present in SubjectSerializer(), and I want to reuse the same method in my StudentSerializer() class.
validate_semester() is verifying that semester id exists in semester table before assigning it to the Student or Subject object.
from rest_framework import serializers
from .models import *
from .helpers import SEMESTER_NOT_STORED
class SemesterSerializer(serializers.Serializer):
id = serializers.IntegerField(required=False)
name = serializers.CharField(max_length=100, required=False)
class SubjectSerializer(serializers.ModelSerializer):
semester = SemesterSerializer()
class Meta:
model = Subject
fields = ["id", "name", "code", "semester"]
def create(self, validated_data):
semester = validated_data.pop("semester")
serializer = SemesterSerializer(semester)
subject = Subject.objects.create(
semester_id=serializer.data["id"], **validated_data
)
return subject
def validate_semester(self, value):
id = value.get("id")
try:
Semester.objects.get(id=id)
except Semester.DoesNotExist:
raise serializers.ValidationError({"id":[SEMESTER_NOT_STORED.format(id)]})
return value
class SemesterSubjectSerializer(serializers.ModelSerializer):
subjects = SubjectSerializer(many=True, read_only=True)
class Meta:
model = Semester
fields = ["id", "name", "subjects"]
class StudentSerializer(serializers.ModelSerializer):
semester = SemesterSerializer()
class Meta:
model = Student
fields = ["id", "name", "email", "semester"]
def create(self, validated_data):
semester = validated_data.pop("semester")
serializer = SemesterSerializer(semester)
student = Student.objects.create(
id=None, semester_id=serializer.data["id"], **validated_data
)
return student
I have try adding validation at the model level as well, but it doesn't seem to be working out. I am getting an IntegrityError.
from django.core.validators import MinLengthValidator, MaxLengthValidator
from .helpers import SEMESTER_NOT_STORED
def validate_semester(id):
semesters = list(Semester.objects.all().values_list("id", flat=True))
if id not in semesters:
raise ValueError({"id":[SEMESTER_NOT_STORED.format(id)]})
class Semester(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Student(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
semester = models.ForeignKey(Semester, on_delete=models.DO_NOTHING, default=None, validators=[validate_semester])
Create a common serializer with serializer
PrimaryKeyRelatedField. It will only allow the existing semester instance. No need to validate manually. Inherit the common serializer class in both semester & student serializer classes. No need to write validate & create methods. Refer rest framework's serializer documentation for more knowledge about serializer Fields. click here for documentaion