3

I'm trying to create a custom serializer method that counts the number of passed and failed quizzes from my QuizResults model. A failed quiz is under .7 and a passed quiz is .7 or over.

I want to be able to look into the Users QuizResult and count the number of passed quizzes(.7 or over). I would then duplicate the method to count the failed quizzes (under .7).

So far I don't have much idea on how to do so. I want to be able to grab the percent_correct field of the model and do a calculation and add it to a field in the serializer called "quiz_passed".

Here is my QuizResult model:

class QuizResult(models.Model):
    quiz = models.ForeignKey(Quiz)
    user = models.ForeignKey(User, related_name='quiz_parent')
    percent_correct = models.FloatField(validators=[MinValueValidator(0.0), MaxValueValidator(1.0)])
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
         return 'Quiz Results for : ' + self.quiz.title

Here is my serializer:

class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    todo_count = serializers.IntegerField(source='todo_parent.count', read_only=True)
    discussion_count = serializers.IntegerField(source='comment_parent.count', read_only=True)
    quiz_passed = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('todo_count', 'discussion_count', 'quiz_passed', 'username', )

    def get_quiz_passed(self, obj):
        return passed

Any help is appreciated.

Edit:

I extended the User model and added a model method like you suggested.

class Profile(User):

    def get_quizzes_passed_count(self):
        return self.quiz_parent.filter(percent_correct__gte=0.8).count()

I then added your suggestion to my ProfileSerializer.

class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    todo_count = serializers.IntegerField(source='todo_parent.count', read_only=True)
    discussion_count = serializers.IntegerField(source='comment_parent.count', read_only=True)
    num_quizzes_passed = serializers.ReadOnlyField(source="get_quizzes_passed_count")

class Meta:
    model = Profile
    fields = ('todo_count', 'discussion_count', 'num_quizzes_passed', 'username')

Unfortunately when I add this nothing appears in the framework once these have been added. Any suggestions? Thank you.

1 Answer 1

4

You can use a model method on the user model to count that user's number of passed quizzes:

class User(models.model):
    # rest of your User attributes
    def get_quizzes_passed_count(self):
        return self.quiz_parent.filter(percent_correct__gte=0.7).count()

Then add that to your serializer using a DRF ReadOnlyField to serialize that method:

class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    todo_count = serializers.IntegerField(
        source='todo_parent.count', read_only=True
    )
    discussion_count = serializers.IntegerField(
        source='comment_parent.count', read_only=True
    )
    quiz_passed = serializers.SerializerMethodField()
    num_quizzes_passed = serializers.ReadOnlyField(source="get_quizzes_passed_count")

    class Meta:
        model = User
        fields = ('todo_count', 'discussion_count', 'quiz_passed', 'username', )

    def get_quiz_passed(self, obj):
        return passed

You can duplicate this for the number of failed quizzes.

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

3 Comments

return self.quiz_parent.filter(percent_correct>0.7).count() needs to be return self.quiz_parent.filter(percent_correct__gte=0.7).count()
I applied your suggestions, but they did not work. Can you check my edit? Thank you for the help!
@Ryan113 I'm not sure - it could be with how you extended the User model, which isn't as straightforward as just extending a regular model class. I would suggest starting a new question with the specific problem.

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.