Files
training-software/courses/serializers.py
Paperclip CTO 4f7f72798f
Some checks failed
CI Build / Build Container (push) Successful in 5s
CI Quality / Ruff Lint (push) Failing after 6s
CI Security / Bandit + pip-audit (push) Successful in 19s
CI Tests / Django Tests (push) Failing after 32s
CI Tests / OpenAPI Schema (push) Has been skipped
TRA-437 Add course frontend and backend API
Backend (courses app):
- courses/serializers.py: Course, Module, Lesson, Page, Enrollment, PageProgress serializers
- courses/views.py: CourseListView, CourseDetailView, CourseEnrollView,
  CourseMyProgressView, MyEnrollmentsView, PageDetailView
- courses/urls.py: expose all 6 endpoints under /api/v1/courses/

Frontend:
- courses.html + courses.js: course catalog with "Meine Kurse" and "Alle Kurse"
  sections, enroll button with toast feedback, progress bars
- course-player.html + course-player.js: full-screen player with collapsible
  sidebar nav (module → lesson → page tree), page content renderer
  (text/video/embed), dwell gate, prev/next navigation, enrollment CTA,
  completion screen
- courses.css: course grid, player layout, sidebar nav, progress bar, dwell gate
- Add Kurse nav link to meetings.html, attendance.html
- Update index.html hero and workflow grid to include Kurse

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-20 00:13:21 +02:00

102 lines
3.4 KiB
Python

from django.db.models import Count
from rest_framework import serializers
from tracking.models import Enrollment, PageProgress
from .models import Course, Lesson, Module, Page
class PageSummarySerializer(serializers.ModelSerializer):
class Meta:
model = Page
fields = ["id", "title", "order", "content_type", "is_required", "required_seconds"]
class PageDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Page
fields = ["id", "title", "order", "content_type", "content_body", "is_required", "required_seconds"]
class LessonSerializer(serializers.ModelSerializer):
pages = PageSummarySerializer(many=True, read_only=True)
class Meta:
model = Lesson
fields = ["id", "title", "order", "pages"]
class ModuleSerializer(serializers.ModelSerializer):
lessons = LessonSerializer(many=True, read_only=True)
class Meta:
model = Module
fields = ["id", "title", "order", "lessons"]
class EnrollmentSerializer(serializers.ModelSerializer):
course_id = serializers.UUIDField(source="course.id", read_only=True)
course_title = serializers.CharField(source="course.title", read_only=True)
course_slug = serializers.SlugField(source="course.slug", read_only=True)
course_description = serializers.CharField(source="course.description", read_only=True)
progress_percent = serializers.SerializerMethodField()
class Meta:
model = Enrollment
fields = [
"id", "course_id", "course_title", "course_slug", "course_description",
"enrolled_at", "completed_at", "progress_percent",
]
read_only_fields = fields
def get_progress_percent(self, obj):
return getattr(obj, "_progress_percent", 0)
class CourseSummarySerializer(serializers.ModelSerializer):
module_count = serializers.IntegerField(read_only=True)
my_enrollment = serializers.SerializerMethodField()
class Meta:
model = Course
fields = ["id", "title", "slug", "description", "module_count", "is_published", "my_enrollment", "updated_at"]
def get_my_enrollment(self, obj):
enrollment = getattr(obj, "_my_enrollment", None)
if enrollment is None:
return None
return {
"id": str(enrollment.id),
"enrolled_at": enrollment.enrolled_at,
"completed_at": enrollment.completed_at,
"progress_percent": getattr(enrollment, "_progress_percent", 0),
}
class CourseDetailSerializer(serializers.ModelSerializer):
modules = ModuleSerializer(many=True, read_only=True)
my_enrollment = serializers.SerializerMethodField()
class Meta:
model = Course
fields = ["id", "title", "slug", "description", "version", "is_published", "modules", "my_enrollment", "updated_at"]
def get_my_enrollment(self, obj):
enrollment = getattr(obj, "_my_enrollment", None)
if enrollment is None:
return None
return {
"id": str(enrollment.id),
"enrolled_at": enrollment.enrolled_at,
"completed_at": enrollment.completed_at,
"progress_percent": getattr(enrollment, "_progress_percent", 0),
}
class PageProgressSerializer(serializers.ModelSerializer):
page_id = serializers.UUIDField(source="page_id", read_only=True)
class Meta:
model = PageProgress
fields = ["page_id", "is_complete", "accumulated_seconds", "last_seen_at"]