1

I want to add an extra key-value pair from the data that I passed to the serializer however this error occurs:

ValueError: Cannot assign "1": "ExamLog.student" must be a "Students" instance.

serializers.py

class ExamSubmitSerializer(serializers.ModelSerializer):
    def to_internal_value(self, data):
        x = get_score(data['exam']) # This will result to 1, I have no errors with this one
        data['score'] = x 
        return data

    class Meta:
        model = ExamLog
        fields = ('student', 'score', 'exam_started')

    # Will use this one for auto-email and auto-pdf creation
    # def create(self, validated_data):
    #   # print "-----"
    #   # y = validated_data.pop('exam', None)
    #   # print y
    #   print validated_data
        # x = self.Meta.model(**validated_data)
        # x.save()

views.py

@api_view(['POST'])
def submitExam(request):
    if request.method == 'POST':
        data = request.data
        student = data.get('student', None)
        exam = data.get('exam', None)
        serializer = ExamSubmitSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(standardResponse(data=serializer.data), status=status.HTTP_201_CREATED)
        else:
            return Response(standardResponse(errors=serializer.errors), status=status.HTTP_400_BAD_REQUEST)

urls.py

urlpatterns = [
  # url(r'^view/', views.viewExams),
  url(r'^view/', views.getQuestion),
  url(r'^add/', views.addUpdateQuestion),
  url(r'^submit/', views.submitExam),
  url(r'^', views.filterQuestions),
]

models.py

class Choices(models.Model):
    question = models.ForeignKey(Questions)
    choice = models.TextField()
    correct = models.NullBooleanField()

    def __unicode__(self):
        return self.choice

class ExamLog(models.Model):
    student = models.ForeignKey(Students)
    # answers = models.JSONField? # To be used for data science statistical purposes
    score = models.PositiveIntegerField(null=True, blank=True, default=None)
    exam_started = models.DateTimeField(null=True, blank=True, default=None)
    exam_finished = models.DateTimeField(auto_now_add=True)

get_score method:

def get_score(answers):
    x  = Choices.objects.filter(id__in=answers).filter(correct=1)
    return x.count()

Sample Request to API:

{"student":1, "exam":[ 1597, 1620, 1906, 1648, 1656, 1718, 1611, 1551, 1812, 1745, 1489, 1815, 1527, 1485, 1512, 1831, 1545, 1713, 1808, 1530 ]}

I understand what the error meant. An instance of the model should be passed instead of its id however this error does not occur and actually saves when I don't include the to_internal_value() method. However this will result for the score to be null

I want to add a value on the score which will come from the exam key of the data

1 Answer 1

3
def to_internal_value(self, data):
    x = get_score(data['exam']) # This will result to 1, I have no errors with this one
    data['score'] = x

    data = super(ExamSubmitSerializer, self).to_internal_value(data)

    return data

Calling super on the method before returning the data will allow to clean again the data together with the manipulated score data key-value.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.