Files
LMS/lmsege/lms/admin.py
T
2026-09-19 15:38:50 +03:00

117 lines
4.7 KiB
Python

from django.contrib import admin
from unfold.admin import ModelAdmin, StackedInline
from django.db import models
from django.forms import widgets
from .models import Subject, Assignment, Submission, Question, Answer
@admin.register(Subject)
class SubjectAdmin(ModelAdmin):
list_display = ('name',)
list_display_links = ('name',)
class QuestionInline(StackedInline):
model = Question
extra = 1
class Media:
js = ('js/admin_assignment.js',)
@admin.register(Assignment)
class AssignmentAdmin(ModelAdmin):
list_display = ('title', 'subject', 'is_published', 'created_at')
list_display_links = ('title',)
list_filter = ('subject', 'is_published')
search_fields = ('title', 'description')
exclude = ('created_by',)
filter_horizontal = ('assigned_students',)
inlines = [QuestionInline]
actions = ['make_published', 'make_unpublished', 'delete_selected_assignments']
@admin.action(description="Опубликовать выбранные задания")
def make_published(self, request, queryset):
updated = queryset.update(is_published=True)
self.message_user(request, f"Опубликовано {updated} заданий.")
@admin.action(description="Скрыть выбранные задания (в черновик)")
def make_unpublished(self, request, queryset):
updated = queryset.update(is_published=False)
self.message_user(request, f"Скрыто {updated} заданий.")
@admin.action(description="Удалить выбранные задания")
def delete_selected_assignments(self, request, queryset):
deleted_count = 0
for obj in queryset:
if self.has_delete_permission(request, obj):
obj.delete()
deleted_count += 1
self.message_user(request, f"Успешно удалено {deleted_count} заданий.")
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser or request.user.role == 'ADMIN':
return qs
return qs.filter(created_by=request.user)
def save_model(self, request, obj, form, change):
if getattr(obj, 'created_by_id', None) is None:
obj.created_by = request.user
super().save_model(request, obj, form, change)
def has_delete_permission(self, request, obj=None):
if request.user.is_superuser or request.user.role == 'ADMIN':
return True
if request.user.role == 'TEACHER':
if obj is not None and obj.created_by != request.user:
return False
return True
return False
from django.utils.html import format_html
class AnswerInline(StackedInline):
model = Answer
extra = 0
readonly_fields = ('question', 'get_student_answer')
fields = ('question', 'get_student_answer', 'is_correct', 'points', 'comment')
def get_student_answer(self, obj):
if not obj or not obj.pk:
return ""
if obj.question.question_type == 'TEXT_AUTO':
return obj.text_answer or "Нет ответа"
elif obj.question.question_type == 'TABLE_AUTO':
import json
try:
data = json.loads(obj.text_answer)
html = '<table style="border-collapse: collapse; margin-top: 4px;">'
for row in data:
html += f'<tr><td style="border: 1px solid #e5e7eb; padding: 4px 8px;">{row[0]}</td><td style="border: 1px solid #e5e7eb; padding: 4px 8px;">{row[1]}</td></tr>'
html += '</table>'
return format_html(html)
except Exception:
return obj.text_answer or "Нет ответа"
else:
if obj.file_answer:
return format_html('<a href="{}" target="_blank">Скачать файл</a>', obj.file_answer.url)
return "Файл не прикреплен"
get_student_answer.short_description = 'Ответ ученика'
def has_add_permission(self, request, obj=None):
return False
@admin.register(Submission)
class SubmissionAdmin(ModelAdmin):
change_list_template = "admin/lms/submission/change_list.html"
list_display = ('assignment', 'student', 'status', 'grade', 'submitted_at')
list_filter = ('status', 'assignment__subject', 'student')
search_fields = ('student__username', 'assignment__title')
inlines = [AnswerInline]
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser or request.user.role == 'ADMIN':
return qs
if request.user.role == 'TEACHER':
return qs.filter(assignment__created_by=request.user)
return qs.filter(student=request.user)