Home > Net >  How to only calculate the xp earned at frist try?
How to only calculate the xp earned at frist try?

Time:10-28

So the user can take some quiz and earn xp only at first try. From the second try on I only want to calculate how many correct answer scored but not xp will be earn.

My models:

class ClassAttempt(models.Model):
    user = models.ForeignKey(to=User,on_delete= models.PROTECT, null=True)
    related_class = models.ForeignKey(to=Class, related_name='attempt', on_delete= models.PROTECT, null=True)
    collected_xp = models.IntegerField(null=True, blank=True, default=0)
    status = models.CharField(
        verbose_name='status',
        max_length=20,
        choices=(
            ('no-completed', 'no-completed'),
            ('completed', 'completed'),
        ),
        default='no-completed'
    )
    try_num = models.IntegerField(null=True, blank=True, default=1)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)






class UserClassQuestionsRecord(models.Model):

    user = models.ForeignKey(to=User, related_name='user_class_question_record', on_delete=models.CASCADE, null=True)
    question = models.ForeignKey(to=ClassQuiz, related_name='question_selected', on_delete=models.PROTECT, null=True, blank=True)
    selected_answer = models.ForeignKey(to=QuizAnsClass, related_name='answer_selected',  on_delete=models.PROTECT, null=True, blank=True)
    is_correct = models.CharField(
        verbose_name='status',
        max_length=10,
        choices=(
            ('True', 'True'),
            ('False', 'False'),
        ),
        default=''
    )
    try_num = models.IntegerField(null=True, blank=True, default=1)
    xp_collected = models.IntegerField(null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


My View:

class UserClassScore(ListAPIView):
    """
    Get User Score at the end of each class by Class ID

    Get request
    """
    queryset = ClassAttempt.objects.all()
    serializer_class = UserClassScoreSerializer
    permission_classes = [IsAuthenticated]
    lookup_field = 'id'

    def get_queryset(self):
        queryset = self.queryset.filter(related_class_id=self.kwargs.get('id'), try_num=1)
        if not queryset:
            self.serializer_class = UserClassScoreSerializerNoXp
            return queryset
        else:
            self.serializer_class = UserClassScoreSerializer
            return queryset

My serializers :

class UserClassScoreSerializer(serializers.ModelSerializer):

    score = serializers.SerializerMethodField()

    xp_collected = serializers.SerializerMethodField()

    def get_score(self, obj):

        class_data = UserClassQuestionsRecord.objects.filter(user=self.context['request'].user,
                                                             question__singleclass_id=obj.related_class.id,
                                                             try_num=1,
                                                             is_correct='True').all()

        return class_data.__len__()

    def get_xp_collected(self, obj):

        class_data = UserClassQuestionsRecord.objects.filter(user=self.context['request'].user,
                                                             question__singleclass_id=obj.related_class.id,
                                                             try_num=1,
                                                             is_correct='True').all()

        obj_count = class_data.__len__()

        return obj_count * 10


    class Meta:
        model = Class
        fields = ['score', 'xp_collected']





class UserClassScoreSerializerNoXp(serializers.ModelSerializer):

    score = serializers.SerializerMethodField()

    xp_collected = serializers.SerializerMethodField()

    def get_score(self, obj):
        class_data = UserClassQuestionsRecord.objects.filter(user=self.context['request'].user,
                                                             question__singleclass_id=obj.related_class.id,
                                                             **try_num=2,**
                                                             is_correct='True').all()
        return class_data.__len__()

    def get_xp_collected(self, obj):
        return 0


    class Meta:
        model = Class
        fields = ['score', 'xp_collected']

So try_num is how I'm tracking on which attempt it is. The thing is that the user can take more that 2 attempts let's say to infinitive attempts.

CodePudding user response:

You can get the first object in table using first()

MyModel.objects.first()

so calculate the xp from this result

or

MyModel.objects.all()[:number_for_question_you_want]

example:

MyModel.objects.all()[:5]

also you can use .values() or any other filter you want

  • Related