from django.db import models from django.db.models import F, Window from django.db.models.functions import Rank from django.utils.translation import gettext_lazy as _ from apps.account.models import User class QuizParticipant(models.Model): quiz = models.ForeignKey('quiz.Quiz', on_delete=models.CASCADE, related_name='participants', verbose_name=_('Quiz')) user = models.ForeignKey('account.User', on_delete=models.CASCADE, verbose_name=_('User'), related_name='uquizzes') started_at = models.DateTimeField(verbose_name=_('Started At')) ended_at = models.DateTimeField(verbose_name=_('Ended At')) total_timing = models.PositiveIntegerField(verbose_name=_('Total Timing'), help_text=_('Seconds take to finish the quiz')) question_score = models.PositiveIntegerField(verbose_name=_('Question Score')) timing_score = models.PositiveIntegerField(verbose_name=_('Timing Score')) total_score = models.PositiveIntegerField(verbose_name=_('Total Score')) class Meta: verbose_name = _("Participant") verbose_name_plural = _("Participants") ordering = ("-id",) def __str__(self): return f"Participant: {self.id}, ParticipantName: {self.user}, Quiz: {self.quiz.id}" def __repr__(self): return f"Participant(id={self.id})" @staticmethod def get_user_ranks(quiz_id): return QuizParticipant.objects.filter(quiz_id=quiz_id).annotate( rank=Window( expression=Rank(), order_by=F('total_score').desc() ) ) class ParticipantAnswer(models.Model): CHOICES = [ (1, _('Option 1')), (2, _('Option 2')), (3, _('Option 3')), (4, _('Option 4')), ] participant = models.ForeignKey(QuizParticipant, on_delete=models.CASCADE, related_name='answers', verbose_name=_('Participant')) question = models.ForeignKey("quiz.Question", on_delete=models.CASCADE, verbose_name=_('Question')) option_num = models.PositiveSmallIntegerField(choices=CHOICES, verbose_name=_('Selected Option')) at_time = models.DateTimeField(verbose_name=_('At Time')) answer_timing = models.PositiveSmallIntegerField(default=0, verbose_name=_('Seconds Take to Answer')) class Meta: verbose_name = _("User Quiz Answer") verbose_name_plural = _("User Quiz Answers") ordering = ("-id",) def __str__(self): return f"Participant Answer: {self.id}" def __repr__(self): return f"ParticipantAnswer(id={self.id})"