jsondjangodjango-rest-frameworkdjango-serializer

Issues with Django Rest Framework Serializer for Nested Data Handling


I’m working on a Django project using Django Rest Framework (DRF), and I’m facing issues with serializing and deserializing nested data for my Child model. Here’s a summary of my setup and the problem:

**I have the following Django models: **

class Hobbies(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

class BehaviorChallenges(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

class StandardTestScore(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

class Child(models.Model):
    parent = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    age = models.CharField(max_length=3)
    gender = models.CharField(max_length=20)
    learning_style = models.CharField(max_length=100)
    gpa = models.DecimalField(max_digits=4, decimal_places=2)
    grade = models.CharField(max_length=10)
    hobbies = models.ManyToManyField(Hobbies, related_name="children")
    behavior_challenges = models.ManyToManyField(BehaviorChallenges, related_name="children")
    standard_test_score = models.ManyToManyField(StandardTestScore, through='TestScoreThroughModel', related_name="children")
    adding_date = models.DateField(auto_now_add=True)
    is_active = models.BooleanField(default=False)

    def __str__(self):
        return self.name

class TestScoreThroughModel(models.Model):
    child = models.ForeignKey(Child, on_delete=models.CASCADE)
    standard_test_score = models.ForeignKey(StandardTestScore, on_delete=models.CASCADE)
    score = models.IntegerField()

**Here’s the ChildSerializer that I’ve set up: **

class TestScoreThroughModelSerializer(serializers.ModelSerializer):
    id = serializers.PrimaryKeyRelatedField(queryset=StandardTestScore.objects.all())
    score = serializers.IntegerField()

    class Meta:
        model = TestScoreThroughModel
        fields = ['id', 'score']

class ChildSerializer(serializers.ModelSerializer):
    hobbies = serializers.PrimaryKeyRelatedField(many=True, queryset=Hobbies.objects.all())
    behavior_challenges = serializers.PrimaryKeyRelatedField(many=True, queryset=BehaviorChallenges.objects.all())
    standard_test_score = TestScoreThroughModelSerializer(many=True, source='testscorethroughmodel_set')

    class Meta:
        model = Child
        fields = [
            'parent', 'name', 'age', 'gender', 'learning_style', 'gpa', 'grade', 
            'hobbies', 'behavior_challenges', 'standard_test_score'
        ]

    def create(self, validated_data):
        test_scores_data = validated_data.pop('testscorethroughmodel_set', [])
        child = Child.objects.create(**validated_data)
        for test_score_data in test_scores_data:
            TestScoreThroughModel.objects.create(child=child, **test_score_data)
        return child

**When I send the following JSON payload using Postman, I get validation errors: **

{
    "parent": 1,
    "name": "John Doe",
    "age": "10",
    "gender": "Male",
    "learning_style": "Visual",
    "gpa": "3.5",
    "grade": "5",
    "hobbies": [1, 2],
    "behavior_challenges": [1],
    "standard_test_score": [
        {"id": 1, "score": 85},
        {"id": 2, "score": 90}
    ]
}


Errors:

{
    "hobbies": [
        "Incorrect type. Expected pk value, received str."
    ],
    "behavior_challenges": [
        "Incorrect type. Expected pk value, received str."
    ],
    "standard_test_score": [
        "This field is required."
    ]
}

Checking the Data Types: Ensured that hobbies and behavior_challenges are sent as arrays of integers.

Verifying standard_test_score: Ensured that standard_test_score is sent as an array of objects with id and score.


Solution

  • Your code should work, if settings and views are correct too. I've repeated your code, and everything works correctly. Can you give some information about views?