Fix tuple index out of range in format_html for statistics
This commit is contained in:
+10
-5
@@ -133,6 +133,7 @@ class SubmissionAdmin(ModelAdmin):
|
|||||||
earned = float(parts[0].strip())
|
earned = float(parts[0].strip())
|
||||||
total = float(parts[1].strip())
|
total = float(parts[1].strip())
|
||||||
percentage = (earned / total) * 100 if total > 0 else 0
|
percentage = (earned / total) * 100 if total > 0 else 0
|
||||||
|
percentage_str = f"{percentage:.1f}"
|
||||||
|
|
||||||
is_passed = percentage >= 40
|
is_passed = percentage >= 40
|
||||||
threshold_text = "Выше порога" if is_passed else "Ниже порога (Мин: 40%)"
|
threshold_text = "Выше порога" if is_passed else "Ниже порога (Мин: 40%)"
|
||||||
@@ -156,11 +157,11 @@ class SubmissionAdmin(ModelAdmin):
|
|||||||
</div>
|
</div>
|
||||||
<div style="flex-grow: 1; max-width: 50%; display: flex; flex-direction: column; justify-content: flex-end;">
|
<div style="flex-grow: 1; max-width: 50%; display: flex; flex-direction: column; justify-content: flex-end;">
|
||||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 8px;">
|
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-bottom: 8px;">
|
||||||
<span style="color: #c9d1d9;">Выполнение: <b>{percentage:.1f}%</b></span>
|
<span style="color: #c9d1d9;">Выполнение: <b>{percentage_str}%</b></span>
|
||||||
<span style="color: {color}; font-weight: 500;">{threshold_text}</span>
|
<span style="color: {color}; font-weight: 500;">{threshold_text}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 100%; background-color: #30363d; border-radius: 9999px; height: 6px; overflow: hidden; margin-bottom: 8px;">
|
<div style="width: 100%; background-color: #30363d; border-radius: 9999px; height: 6px; overflow: hidden; margin-bottom: 8px;">
|
||||||
<div style="background-color: {color}; width: {percentage}%; height: 100%; border-radius: 9999px;"></div>
|
<div style="background-color: {color}; width: {percentage_str}%; height: 100%; border-radius: 9999px;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; justify-content: space-between; font-size: 11px; color: #8b949e; font-family: ui-monospace, SFMono-Regular, monospace;">
|
<div style="display: flex; justify-content: space-between; font-size: 11px; color: #8b949e; font-family: ui-monospace, SFMono-Regular, monospace;">
|
||||||
<span>0 б</span>
|
<span>0 б</span>
|
||||||
@@ -172,14 +173,18 @@ class SubmissionAdmin(ModelAdmin):
|
|||||||
</div>
|
</div>
|
||||||
''',
|
''',
|
||||||
grade=obj.grade,
|
grade=obj.grade,
|
||||||
percentage=percentage,
|
percentage_str=percentage_str,
|
||||||
threshold_text=threshold_text,
|
threshold_text=threshold_text,
|
||||||
color=color,
|
color=color,
|
||||||
total_int=total_int,
|
total_int=total_int,
|
||||||
threshold_points=threshold_points
|
threshold_points=threshold_points
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception as e:
|
||||||
return format_html('<div style="color: #f85149;">Оценка имеет неверный формат. Используйте формат "X/Y" (например, "3/27").</div>')
|
return format_html(
|
||||||
|
'<div style="color: #f85149;">Оценка имеет неверный формат. Ошибка: {error}<br>Значение: "{val}"</div>',
|
||||||
|
error=str(e),
|
||||||
|
val=obj.grade
|
||||||
|
)
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
qs = super().get_queryset(request)
|
qs = super().get_queryset(request)
|
||||||
|
|||||||
@@ -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='Статус'),
|
||||||
|
),
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user