102 lines
No EOL
3.2 KiB
Python
102 lines
No EOL
3.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 .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):
|
|
# 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) |