These are my models : 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
I want to have an updateserializer for updating, but the field "type" in the Test model, only can be updated if there is no question in Skillarea model which related to Test model( has the same id as updating test, in its test field)
I wrote these serializer and view but it doesnt know data['id']
which i used in validator and sends 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)
CodePudding user response:
I think you can get the id
from instance
attribute.
class TestUpdateAPIViewSerializer(serializers.ModelSerializer):
def validate(self, data):
questions = SkillArea.objects.filter(test=self.instance.id, questions__isnull=False)
...