Как рассчитать только xp, полученный при первой попытке?

Пользователь может пройти некоторый тест и заработать xp только при первой попытке. Со второй попытки я хочу только подсчитать количество правильных ответов, но не заработать xp.

Мои модели:

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)


Мое мнение:

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

Мои сериализаторы :

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']

Так try_num - это то, как я отслеживаю, какая это попытка. Дело в том, что пользователь может предпринять более 2 попыток, скажем, до инфинитивных попыток

Вы можете получить первый объект в таблице, используя first()

MyModel.objects.first()

вычислите xp из этого результата

или

MyModel.objects.all()[:number_for_question_you_want]

пример:

MyModel.objects.all()[:5]

также вы можете использовать .values() или любой другой фильтр, который вы хотите

Вернуться на верх