Django restframework object-level-validation

Вот мои модели: Test, Skillarea, question

MODELS.PY :


class Test(BaseModel):

    types = models.ManyToManyField(
        TestType,
        related_name='tests',
    )
    title = models.CharField(max_length=255)
    summary = models.TextField()


    def __str__(self):
        return self.title
class SkillArea(BaseModel):
    title = models.CharField(max_length=255)
    test = models.ForeignKey('Test', on_delete=models.PROTECT, related_name='skill_areas')
    questions = models.ManyToManyField(
        'assessment.Question',
        related_name='skill_areas',
    )

    def __str__(self):
        return self.title


class Question(BaseModel):
   
    question_text = models.TextField()

    def get_absolute_url(self):
        self.get_type_display()

    def __str__(self):
        return truncatewords(self.question_text, 7)

class TestType(BaseModel):
    title = models.CharField(max_length=255)

    def __str__(self):
        return self.title

Я хочу иметь updateerializer для обновления, но поле "type" в модели Test, может быть обновлено только если нет вопроса в модели Skillarea, который связан с моделью Test (имеет тот же id, что и обновляемый тест, в его поле test)

Я написал эти сериализатор и представление, но оно не знает data['id'], который я использовал в валидаторе и посылает KeyError: 'id'

serializer.py :

class TestUpdateAPIViewSerializer(serializers.ModelSerializer):

    def validate(self, data):
        questions = SkillArea.objects.filter(test=data['id'], questions__isnull=False)
        if questions.exists():
            raise serializers.ValidationError("You may not edit type")
        return data

    class Meta:
        model = Test
        fields = (

            'id',
            'types',
            'title',
            'summary',
          
        )

Views.py :

class TestUpdateAPIView(APIView):

    def patch(self, request, pk):
        test = Test.active_objects.get(pk=pk)
        serializer = TestUpdateAPIViewSerializer(instance=test, partial=True, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)

Я думаю, что вы можете получить id из instance атрибута.

class TestUpdateAPIViewSerializer(serializers.ModelSerializer):

    def validate(self, data):
        questions = SkillArea.objects.filter(test=self.instance.id, questions__isnull=False)
        ...
    
Вернуться на верх