2024-10-05 00:55:24 +03:00

464 lines
15 KiB
Python

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Sum
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.decorators import method_decorator
from django.views.generic import CreateView
from django_filters.views import FilterView
from accounts.decorators import lecturer_required, student_required
from accounts.models import Student
from core.models import Semester
from course.filters import CourseAllocationFilter, ProgramFilter
from course.forms import (
CourseAddForm,
CourseAllocationForm,
EditCourseAllocationForm,
ProgramForm,
UploadFormFile,
UploadFormVideo,
)
from course.models import (
Course,
CourseAllocation,
Program,
Upload,
UploadVideo,
)
from result.models import TakenCourse
# ########################################################
# Program Views
# ########################################################
@method_decorator([login_required, lecturer_required], name="dispatch")
class ProgramFilterView(FilterView):
filterset_class = ProgramFilter
template_name = "course/program_list.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = "Programs"
return context
@login_required
@lecturer_required
def program_add(request):
if request.method == "POST":
form = ProgramForm(request.POST)
if form.is_valid():
program = form.save()
messages.success(request, f"{program.title} program has been created.")
return redirect("programs")
messages.error(request, "Correct the error(s) below.")
else:
form = ProgramForm()
return render(
request, "course/program_add.html", {"title": "Add Program", "form": form}
)
@login_required
def program_detail(request, pk):
program = get_object_or_404(Program, pk=pk)
courses = Course.objects.filter(program_id=pk).order_by("-year")
credits = courses.aggregate(total_credits=Sum("credit"))
paginator = Paginator(courses, 10)
page = request.GET.get("page")
courses = paginator.get_page(page)
return render(
request,
"course/program_single.html",
{
"title": program.title,
"program": program,
"courses": courses,
"credits": credits,
},
)
@login_required
@lecturer_required
def program_edit(request, pk):
program = get_object_or_404(Program, pk=pk)
if request.method == "POST":
form = ProgramForm(request.POST, instance=program)
if form.is_valid():
program = form.save()
messages.success(request, f"{program.title} program has been updated.")
return redirect("programs")
messages.error(request, "Correct the error(s) below.")
else:
form = ProgramForm(instance=program)
return render(
request, "course/program_add.html", {"title": "Edit Program", "form": form}
)
@login_required
@lecturer_required
def program_delete(request, pk):
program = get_object_or_404(Program, pk=pk)
title = program.title
program.delete()
messages.success(request, f"Program {title} has been deleted.")
return redirect("programs")
# ########################################################
# Course Views
# ########################################################
@login_required
def course_single(request, slug):
course = get_object_or_404(Course, slug=slug)
files = Upload.objects.filter(course__slug=slug)
videos = UploadVideo.objects.filter(course__slug=slug)
lecturers = CourseAllocation.objects.filter(courses__pk=course.id)
return render(
request,
"course/course_single.html",
{
"title": course.title,
"course": course,
"files": files,
"videos": videos,
"lecturers": lecturers,
"media_url": settings.MEDIA_URL,
},
)
@login_required
@lecturer_required
def course_add(request, pk):
program = get_object_or_404(Program, pk=pk)
if request.method == "POST":
form = CourseAddForm(request.POST)
if form.is_valid():
course = form.save()
messages.success(
request, f"{course.title} ({course.code}) has been created."
)
return redirect("program_detail", pk=program.pk)
messages.error(request, "Correct the error(s) below.")
else:
form = CourseAddForm(initial={"program": program})
return render(
request,
"course/course_add.html",
{"title": "Add Course", "form": form, "program": program},
)
@login_required
@lecturer_required
def course_edit(request, slug):
course = get_object_or_404(Course, slug=slug)
if request.method == "POST":
form = CourseAddForm(request.POST, instance=course)
if form.is_valid():
course = form.save()
messages.success(
request, f"{course.title} ({course.code}) has been updated."
)
return redirect("program_detail", pk=course.program.pk)
messages.error(request, "Correct the error(s) below.")
else:
form = CourseAddForm(instance=course)
return render(
request, "course/course_add.html", {"title": "Edit Course", "form": form}
)
@login_required
@lecturer_required
def course_delete(request, slug):
course = get_object_or_404(Course, slug=slug)
title = course.title
program_id = course.program.id
course.delete()
messages.success(request, f"Course {title} has been deleted.")
return redirect("program_detail", pk=program_id)
# ########################################################
# Course Allocation Views
# ########################################################
@method_decorator([login_required, lecturer_required], name="dispatch")
class CourseAllocationFormView(CreateView):
form_class = CourseAllocationForm
template_name = "course/course_allocation_form.html"
def form_valid(self, form):
lecturer = form.cleaned_data["lecturer"]
selected_courses = form.cleaned_data["courses"]
allocation, created = CourseAllocation.objects.get_or_create(lecturer=lecturer)
allocation.courses.set(selected_courses)
messages.success(
self.request, f"Courses allocated to {lecturer.get_full_name} successfully."
)
return redirect("course_allocation_view")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = "Assign Course"
return context
@method_decorator([login_required, lecturer_required], name="dispatch")
class CourseAllocationFilterView(FilterView):
filterset_class = CourseAllocationFilter
template_name = "course/course_allocation_view.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = "Course Allocations"
return context
@login_required
@lecturer_required
def edit_allocated_course(request, pk):
allocation = get_object_or_404(CourseAllocation, pk=pk)
if request.method == "POST":
form = EditCourseAllocationForm(request.POST, instance=allocation)
if form.is_valid():
form.save()
messages.success(request, "Course allocation has been updated.")
return redirect("course_allocation_view")
messages.error(request, "Correct the error(s) below.")
else:
form = EditCourseAllocationForm(instance=allocation)
return render(
request,
"course/course_allocation_form.html",
{"title": "Edit Course Allocation", "form": form},
)
@login_required
@lecturer_required
def deallocate_course(request, pk):
allocation = get_object_or_404(CourseAllocation, pk=pk)
allocation.delete()
messages.success(request, "Successfully deallocated courses.")
return redirect("course_allocation_view")
# ########################################################
# File Upload Views
# ########################################################
@login_required
@lecturer_required
def handle_file_upload(request, slug):
course = get_object_or_404(Course, slug=slug)
if request.method == "POST":
form = UploadFormFile(request.POST, request.FILES)
if form.is_valid():
upload = form.save(commit=False)
upload.course = course
upload.save()
messages.success(request, f"{upload.title} has been uploaded.")
return redirect("course_detail", slug=slug)
messages.error(request, "Correct the error(s) below.")
else:
form = UploadFormFile()
return render(
request,
"upload/upload_file_form.html",
{"title": "File Upload", "form": form, "course": course},
)
@login_required
@lecturer_required
def handle_file_edit(request, slug, file_id):
course = get_object_or_404(Course, slug=slug)
upload = get_object_or_404(Upload, pk=file_id)
if request.method == "POST":
form = UploadFormFile(request.POST, request.FILES, instance=upload)
if form.is_valid():
upload = form.save()
messages.success(request, f"{upload.title} has been updated.")
return redirect("course_detail", slug=slug)
messages.error(request, "Correct the error(s) below.")
else:
form = UploadFormFile(instance=upload)
return render(
request,
"upload/upload_file_form.html",
{"title": "Edit File", "form": form, "course": course},
)
@login_required
@lecturer_required
def handle_file_delete(request, slug, file_id):
upload = get_object_or_404(Upload, pk=file_id)
title = upload.title
upload.delete()
messages.success(request, f"{title} has been deleted.")
return redirect("course_detail", slug=slug)
# ########################################################
# Video Upload Views
# ########################################################
@login_required
@lecturer_required
def handle_video_upload(request, slug):
course = get_object_or_404(Course, slug=slug)
if request.method == "POST":
form = UploadFormVideo(request.POST, request.FILES)
if form.is_valid():
video = form.save(commit=False)
video.course = course
video.save()
messages.success(request, f"{video.title} has been uploaded.")
return redirect("course_detail", slug=slug)
messages.error(request, "Correct the error(s) below.")
else:
form = UploadFormVideo()
return render(
request,
"upload/upload_video_form.html",
{"title": "Video Upload", "form": form, "course": course},
)
@login_required
def handle_video_single(request, slug, video_slug):
course = get_object_or_404(Course, slug=slug)
video = get_object_or_404(UploadVideo, slug=video_slug)
return render(
request,
"upload/video_single.html",
{"video": video, "course": course},
)
@login_required
@lecturer_required
def handle_video_edit(request, slug, video_slug):
course = get_object_or_404(Course, slug=slug)
video = get_object_or_404(UploadVideo, slug=video_slug)
if request.method == "POST":
form = UploadFormVideo(request.POST, request.FILES, instance=video)
if form.is_valid():
video = form.save()
messages.success(request, f"{video.title} has been updated.")
return redirect("course_detail", slug=slug)
messages.error(request, "Correct the error(s) below.")
else:
form = UploadFormVideo(instance=video)
return render(
request,
"upload/upload_video_form.html",
{"title": "Edit Video", "form": form, "course": course},
)
@login_required
@lecturer_required
def handle_video_delete(request, slug, video_slug):
video = get_object_or_404(UploadVideo, slug=video_slug)
title = video.title
video.delete()
messages.success(request, f"{title} has been deleted.")
return redirect("course_detail", slug=slug)
# ########################################################
# Course Registration Views
# ########################################################
@login_required
@student_required
def course_registration(request):
student = get_object_or_404(Student, student__pk=request.user.id)
current_semester = Semester.objects.filter(is_current_semester=True).first()
if not current_semester:
messages.error(request, "No active semester found.")
return render(request, "course/course_registration.html")
if request.method == "POST":
course_ids = request.POST.getlist("course_ids")
for course_id in course_ids:
course = get_object_or_404(Course, pk=course_id)
TakenCourse.objects.get_or_create(student=student, course=course)
messages.success(request, "Courses registered successfully!")
return redirect("course_registration")
taken_course_ids = TakenCourse.objects.filter(student=student).values_list(
"course__id", flat=True
)
courses = Course.objects.filter(
program=student.program,
level=student.level,
semester=current_semester.semester,
).exclude(id__in=taken_course_ids)
registered_courses = Course.objects.filter(id__in=taken_course_ids)
all_courses = Course.objects.filter(level=student.level, program=student.program)
context = {
"courses": courses,
"registered_courses": registered_courses,
"student": student,
"current_semester": current_semester,
"all_courses_registered": all_courses.count() == registered_courses.count(),
}
return render(request, "course/course_registration.html", context)
@login_required
@student_required
def course_drop(request):
if request.method == "POST":
student = get_object_or_404(Student, student__pk=request.user.id)
course_ids = request.POST.getlist("course_ids")
for course_id in course_ids:
course = get_object_or_404(Course, pk=course_id)
TakenCourse.objects.filter(student=student, course=course).delete()
messages.success(request, "Courses dropped successfully!")
return redirect("course_registration")
# ########################################################
# User Course List View
# ########################################################
@login_required
def user_course_list(request):
if request.user.is_lecturer:
courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id)
return render(request, "course/user_course_list.html", {"courses": courses})
if request.user.is_student:
student = get_object_or_404(Student, student__pk=request.user.id)
taken_courses = TakenCourse.objects.filter(student=student)
return render(
request,
"course/user_course_list.html",
{"student": student, "taken_courses": taken_courses},
)
# For other users
return render(request, "course/user_course_list.html")