117 lines
4.8 KiB
Python
117 lines
4.8 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 = 0
|
|
|
|
class Media:
|
|
js = ('js/admin_assignment.js',)
|
|
|
|
@admin.register(Assignment)
|
|
class AssignmentAdmin(ModelAdmin):
|
|
list_display = ('title', 'subject', 'is_published', 'is_closed', 'deadline', 'created_at')
|
|
list_display_links = ('title',)
|
|
list_filter = ('subject', 'is_published', 'is_closed')
|
|
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)
|