You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

122 lines
5.2 KiB

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','go_to_course']
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_exclude(self, request, obj=None):
if not obj: # اگر obj وجود ندارد یعنی صفحه Add است
return ['course']
return []
# 🔔 قفل کردن (Readonly) فیلد کورس در زمان مشاهده و ویرایش
def get_readonly_fields(self, request, obj=None):
if obj: # اگر obj وجود دارد یعنی صفحه Change/Detail است
return ['course']
return []
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'<span class="unfold-badge unfold-badge--success">{_("Active")}</span>')
return mark_safe(f'<span class="unfold-badge unfold-badge--warning">{_("Inactive")}</span>')
@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'<a href="{url}" class="unfold-link">{_("Questions")}: {obj.questions_count}</a>')
# 🔔 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)
@action(
description=_("View Course"),
icon="school", # آیکون کلاه فارغ‌التحصیلی
)
def go_to_course(self, request, object_id):
"""دکمه‌ای برای رفتن به صفحه جزئیات کورسِ این کوییز"""
quiz = self.get_object(request, object_id)
# پیدا کردن کورس از طریق درس (Lesson)
if quiz and quiz.lesson and quiz.lesson.course_id:
url = reverse('admin:course_course_change', args=[quiz.lesson.course_id])
return redirect(url)
messages.error(request, _("Course not found for this quiz."))
return redirect(request.META.get('HTTP_REFERER', '/'))
project_admin_site.register(Quiz, QuizAdmin)