from django.contrib import admin from django.db.models import F from django.contrib.admin import SimpleListFilter from django.utils.translation import gettext_lazy as _ from unfold.admin import ModelAdmin, StackedInline from unfold.decorators import display from apps.quiz.models import QuizParticipant, ParticipantAnswer from apps.account.models import User from utils.admin import project_admin_site class ParticipantAnswerInline(StackedInline): model = ParticipantAnswer readonly_fields = ( 'correct_answer_display', 'question', 'at_time', 'answer_timing', ) @display(description="Correct Answer") def correct_answer_display(self, obj): return obj.correct_answer def has_add_permission(self, request, obj): return False def has_delete_permission(self, request, obj=None): return False def get_queryset(self, request): return super().get_queryset(request).annotate(correct_answer=F('question__correct_answer')) class UserEmailFilter(SimpleListFilter): title = _('User Email') parameter_name = 'user_email' def lookups(self, request, model_admin): users = User.objects.all() return [(user.email, user.email) for user in users] def queryset(self, request, queryset): if self.value(): email = self.value().replace('%40', '@') return queryset.filter(user__email=email) return queryset class ParticipantAdmin(ModelAdmin): inlines = [ParticipantAnswerInline] search_fields = ['user__username', 'user__fullname'] list_display = [ 'quiz', 'user', 'started_at', 'ended_at', 'total_timing', 'question_score', 'timing_score', 'total_score' ] list_filter = ['started_at', 'ended_at', 'quiz__status', UserEmailFilter] # Optional: Add these for better UI experience date_hierarchy = 'started_at' ordering = ['-started_at'] project_admin_site.register(QuizParticipant, ParticipantAdmin)