diff --git a/lmsege/lms/admin.py b/lmsege/lms/admin.py index 8fbe1d6..923e4d5 100644 --- a/lmsege/lms/admin.py +++ b/lmsege/lms/admin.py @@ -133,6 +133,7 @@ class SubmissionAdmin(ModelAdmin): earned = float(parts[0].strip()) total = float(parts[1].strip()) percentage = (earned / total) * 100 if total > 0 else 0 + percentage_str = f"{percentage:.1f}" is_passed = percentage >= 40 threshold_text = "Выше порога" if is_passed else "Ниже порога (Мин: 40%)" @@ -156,11 +157,11 @@ class SubmissionAdmin(ModelAdmin):
- Выполнение: {percentage:.1f}% + Выполнение: {percentage_str}% {threshold_text}
-
+
0 б @@ -172,14 +173,18 @@ class SubmissionAdmin(ModelAdmin):
''', grade=obj.grade, - percentage=percentage, + percentage_str=percentage_str, threshold_text=threshold_text, color=color, total_int=total_int, threshold_points=threshold_points ) - except Exception: - return format_html('
Оценка имеет неверный формат. Используйте формат "X/Y" (например, "3/27").
') + except Exception as e: + return format_html( + '
Оценка имеет неверный формат. Ошибка: {error}
Значение: "{val}"
', + error=str(e), + val=obj.grade + ) def get_queryset(self, request): qs = super().get_queryset(request) diff --git a/lmsege/lms/migrations/0011_assignment_allow_late_submissions_and_more.py b/lmsege/lms/migrations/0011_assignment_allow_late_submissions_and_more.py new file mode 100644 index 0000000..598fa82 --- /dev/null +++ b/lmsege/lms/migrations/0011_assignment_allow_late_submissions_and_more.py @@ -0,0 +1,70 @@ +# Generated by Django 5.1.1 on 2026-09-28 19:57 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lms', '0010_question_table_rows_alter_question_correct_answer_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='assignment', + name='allow_late_submissions', + field=models.BooleanField(default=True, help_text='Если включено, ученики смогут сдавать задание после дедлайна с пометкой "После дедлайна".', verbose_name='Разрешить дорешивание'), + ), + migrations.AddField( + model_name='assignment', + name='assign_to_all', + field=models.BooleanField(default=True, help_text='Если включено, задание будет доступно всем ученикам.', verbose_name='Назначить всем'), + ), + migrations.AddField( + model_name='assignment', + name='assigned_students', + field=models.ManyToManyField(blank=True, help_text='Выберите учеников, если задание не для всех.', limit_choices_to={'role': 'STUDENT'}, related_name='assigned_assignments', to=settings.AUTH_USER_MODEL, verbose_name='Назначенные ученики'), + ), + migrations.AddField( + model_name='assignment', + name='deadline', + field=models.DateTimeField(blank=True, help_text='После этого времени ответы не принимаются.', null=True, verbose_name='Дедлайн'), + ), + migrations.AddField( + model_name='assignment', + name='is_published', + field=models.BooleanField(default=True, help_text='Снимите галочку, чтобы скрыть задание (как черновик).', verbose_name='Опубликовано'), + ), + migrations.AddField( + model_name='assignment', + name='short_description', + field=models.TextField(blank=True, help_text='Отображается на главной странице в карточке задания. Если пусто, используется начало полного описания.', null=True, verbose_name='Краткое описание (для карточки)'), + ), + migrations.AddField( + model_name='assignment', + name='time_limit', + field=models.PositiveIntegerField(blank=True, help_text='Например, 235 для 3ч 55м. Оставьте пустым, если без таймера.', null=True, verbose_name='Лимит времени (минуты)'), + ), + migrations.AddField( + model_name='submission', + name='is_late', + field=models.BooleanField(default=False, verbose_name='Сдано после дедлайна'), + ), + migrations.AddField( + model_name='submission', + name='is_time_expired', + field=models.BooleanField(default=False, verbose_name='Время вышло'), + ), + migrations.AddField( + model_name='submission', + name='started_at', + field=models.DateTimeField(blank=True, null=True, verbose_name='Время начала'), + ), + migrations.AlterField( + model_name='submission', + name='status', + field=models.CharField(choices=[('IN_PROGRESS', 'В процессе выполнения'), ('PENDING', 'Ожидает проверки'), ('GRADED', 'Проверено')], default='PENDING', max_length=20, verbose_name='Статус'), + ), + ]