147 lines
No EOL
5.2 KiB
Python
147 lines
No EOL
5.2 KiB
Python
from django.shortcuts import render, get_object_or_404, redirect
|
|
from django.urls import reverse
|
|
from django.views import generic
|
|
from django.db.models import Prefetch
|
|
from .models import Course, Lesson, Module, Comment
|
|
from progression.models import Progression
|
|
from .forms import CommentForm
|
|
|
|
def list_courses(request):
|
|
courses = Course.objects.all()
|
|
return render(request, 'courses/list.html', {'courses': courses})
|
|
|
|
def show(request, course_name, course_id):
|
|
# Optimized course fetch with related author and profile (if present)
|
|
course = get_object_or_404(
|
|
Course.objects.select_related('author', 'author__profile'),
|
|
pk=course_id,
|
|
)
|
|
|
|
# Fetch lessons through module -> course relation and keep a stable order
|
|
lessons = (
|
|
Lesson.objects.filter(module__course_id=course_id)
|
|
.select_related('module')
|
|
.order_by('order')
|
|
)
|
|
|
|
# Récupération de la progression de l'utilisateur sur le cours
|
|
user_progress = None
|
|
completed_lesson_ids = [] # On prépare une liste vide par défaut
|
|
|
|
if request.user.is_authenticated:
|
|
user_progress = Progression.objects.filter(user=request.user, course=course).first()
|
|
|
|
# 2. S'il y a une progression, on extrait juste les IDs des leçons finies
|
|
if user_progress:
|
|
# values_list renvoie une liste simple : [1, 5, 12] au lieu d'objets lourds
|
|
completed_lesson_ids = user_progress.completed_lessons.values_list('id', flat=True)
|
|
|
|
context = {
|
|
'course': course,
|
|
'lessons': lessons,
|
|
'user_progress': user_progress,
|
|
'completed_lesson_ids': completed_lesson_ids,
|
|
}
|
|
return render(request, 'courses/show.html', context)
|
|
|
|
|
|
def lesson_detail(request, course_slug, module_slug, lesson_slug):
|
|
# Fetch course by slug
|
|
course = get_object_or_404(
|
|
Course.objects.select_related('author', 'author__profile'),
|
|
slug=course_slug,
|
|
)
|
|
|
|
# Fetch module within course
|
|
module = get_object_or_404(
|
|
Module.objects.filter(course=course),
|
|
slug=module_slug,
|
|
)
|
|
|
|
# Fetch lesson within module
|
|
lesson = get_object_or_404(
|
|
Lesson.objects.select_related('module').filter(module=module),
|
|
slug=lesson_slug,
|
|
)
|
|
|
|
# Handle comment submission
|
|
if request.method == 'POST':
|
|
if not request.user.is_authenticated:
|
|
login_url = reverse('login')
|
|
return redirect(f"{login_url}?next={request.path}")
|
|
form = CommentForm(request.POST)
|
|
if form.is_valid():
|
|
parent = None
|
|
parent_id = form.cleaned_data.get('parent')
|
|
if parent_id:
|
|
try:
|
|
parent = Comment.objects.get(id=parent_id, lesson=lesson, is_active=True)
|
|
except Comment.DoesNotExist:
|
|
parent = None
|
|
|
|
Comment.objects.create(
|
|
lesson=lesson,
|
|
user=request.user,
|
|
content=form.cleaned_data['content'],
|
|
parent=parent,
|
|
)
|
|
# Redirect to anchor to show the new comment
|
|
return redirect(request.path + "#comments")
|
|
else:
|
|
form = CommentForm()
|
|
|
|
# Lessons list for TOC (entire course ordered)
|
|
lessons = (
|
|
Lesson.objects.filter(module__course=course)
|
|
.select_related('module')
|
|
.order_by('order')
|
|
)
|
|
|
|
# Compute previous and next lessons within the ordered course lessons
|
|
prev_lesson = None
|
|
next_lesson = None
|
|
try:
|
|
ids = list(lessons.values_list('id', flat=True))
|
|
idx = ids.index(lesson.id)
|
|
if idx > 0:
|
|
prev_lesson = next(l for l in lessons if l.id == ids[idx - 1])
|
|
if idx < len(ids) - 1:
|
|
next_lesson = next(l for l in lessons if l.id == ids[idx + 1])
|
|
except ValueError:
|
|
# current lesson not in list — keep prev/next as None
|
|
pass
|
|
|
|
# Public comments for the current lesson (top-level) and their replies
|
|
replies_qs = Comment.objects.filter(is_active=True).select_related('user').order_by('created_at')
|
|
comments = (
|
|
Comment.objects.filter(lesson=lesson, is_active=True, parent__isnull=True)
|
|
.select_related('user')
|
|
.prefetch_related(Prefetch('replies', queryset=replies_qs))
|
|
.order_by('created_at')
|
|
)
|
|
|
|
# Récupération de la progression de l'utilisateur sur le cours
|
|
user_progress = None
|
|
completed_lesson_ids = [] # On prépare une liste vide par défaut
|
|
|
|
if request.user.is_authenticated:
|
|
user_progress = Progression.objects.filter(user=request.user, course=course).first()
|
|
|
|
# 2. S'il y a une progression, on extrait juste les IDs des leçons finies
|
|
if user_progress:
|
|
# values_list renvoie une liste simple : [1, 5, 12] au lieu d'objets lourds
|
|
completed_lesson_ids = user_progress.completed_lessons.values_list('id', flat=True)
|
|
|
|
context = {
|
|
'course': course,
|
|
'module': module,
|
|
'lesson': lesson,
|
|
'lessons': lessons,
|
|
'comments': comments,
|
|
'comment_form': form,
|
|
'prev_lesson': prev_lesson,
|
|
'next_lesson': next_lesson,
|
|
'user_progress': user_progress,
|
|
'completed_lesson_ids': completed_lesson_ids,
|
|
}
|
|
return render(request, 'courses/lesson.html', context) |