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