from django.contrib import admin, messages from django.db.models import Count from django.utils.safestring import mark_safe from django.urls import reverse from django.shortcuts import redirect from django.utils.translation import gettext_lazy as _ from unfold.admin import ModelAdmin from unfold.decorators import display, action from apps.course.models import CourseLesson from apps.quiz.models import Quiz from apps.quiz.admin.question import QuestionAdminInline from apps.quiz.admin.participant import QuizParticipantInline from utils.admin import project_admin_site, admin_url_generator class QuizAdmin(ModelAdmin): search_fields = ['title', 'lesson__title'] list_display = ['title', 'description', 'lesson', 'each_question_timing', 'status_display', 'questions_display'] list_filter = ['each_question_timing', 'status'] inlines = [QuestionAdminInline, QuizParticipantInline] compressed_fields = True # 🔔 ADD THE TOP ACTION BUTTON actions_detail = ['manage_all_participants'] def get_queryset(self, request): queryset = super().get_queryset(request).annotate( questions_count=Count('questions') ) # اولویت اول: staff یا admin - دسترسی کامل if (request.user.is_staff or request.user.has_role('admin') or request.user.has_role('super_admin')): return queryset # اولویت دوم: professor - فقط کوئیزهای دوره‌های خود if request.user.has_role('professor'): return queryset.filter(lesson__course__professor=request.user) return queryset.none() def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) # محدود کردن انتخاب lesson بر اساس سطح دسترسی کاربر if (request.user.is_staff or request.user.has_role('admin') or request.user.has_role('super_admin')): # اولویت اول: staff یا admin - دسترسی کامل form.base_fields['lesson'].queryset = CourseLesson.objects.all() elif request.user.has_role('professor'): # اولویت دوم: professor - فقط CourseLesson های دوره‌های خود form.base_fields['lesson'].queryset = CourseLesson.objects.filter(course__professor=request.user) else: # سایر کاربران - عدم دسترسی form.base_fields['lesson'].queryset = CourseLesson.objects.none() form.base_fields['lesson'].widget.can_add_related = False return form @display(description=_('Status'), ordering='status') def status_display(self, obj): if obj.status: return mark_safe(f'{_("Active")}') return mark_safe(f'{_("Inactive")}') @display(description=_('Questions'), ordering='questions_count') def questions_display(self, obj): url = reverse('admin:quiz_question_changelist') + f'?quiz={obj.id}' return mark_safe(f'{_("Questions")}: {obj.questions_count}') # 🔔 THE REDIRECT LOGIC FOR THE NEW BUTTON @action( description=_("Manage All Participants"), icon="groups", ) def manage_all_participants(self, request, object_id): """Redirect to the pre-filtered Quiz Participant changelist for this quiz.""" quiz = self.get_object(request, object_id) if not quiz: messages.error(request, _("Quiz not found")) return redirect(admin_url_generator(request, "quiz_quiz_changelist")) # Generate base URL for quiz participant list base_url = admin_url_generator(request, "quiz_quizparticipant_changelist") # Append the filter query parameter url = f"{base_url}?quiz__id__exact={object_id}" return redirect(url) project_admin_site.register(Quiz, QuizAdmin)