Add comment system with models, forms, and UI integration for lessons

This commit is contained in:
mrtoine 2025-12-10 22:22:17 +01:00
parent c22622ebc1
commit 95111240bc
26 changed files with 1001 additions and 77 deletions

View file

@ -1,12 +1,102 @@
from django.shortcuts import render, get_object_or_404
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from django.views import generic
from .models import Course, Lesson
from django.db.models import Prefetch
from .models import Course, Lesson, Module, Comment
from .forms import CommentForm
def list(request):
courses = Course.objects.all()
return render(request, 'courses/list.html', {'courses': courses})
def show(request, course_name, course_id):
course = get_object_or_404(Course, pk=course_id)
lessons = Lesson.objects.filter(course_id=course_id)
return render(request, 'courses/show.html', {'course' : course, 'lessons': lessons})
# 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')
)
context = {
'course': course,
'lessons': lessons,
}
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')
)
# 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')
)
context = {
'course': course,
'module': module,
'lesson': lesson,
'lessons': lessons,
'comments': comments,
'comment_form': form,
}
return render(request, 'courses/lesson.html', context)