504 lines
17 KiB
Python
504 lines
17 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):
|
|
if request.method == "POST":
|
|
student = Student.objects.get(student__pk=request.user.id)
|
|
ids = ()
|
|
data = request.POST.copy()
|
|
data.pop("csrfmiddlewaretoken", None) # remove csrf_token
|
|
for key in data.keys():
|
|
ids = ids + (str(key),)
|
|
for s in range(0, len(ids)):
|
|
course = Course.objects.get(pk=ids[s])
|
|
obj = TakenCourse.objects.create(student=student, course=course)
|
|
obj.save()
|
|
messages.success(request, "Courses registered successfully!")
|
|
return redirect("course_registration")
|
|
else:
|
|
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")
|
|
|
|
# student = Student.objects.get(student__pk=request.user.id)
|
|
student = get_object_or_404(Student, student__id=request.user.id)
|
|
taken_courses = TakenCourse.objects.filter(student__student__id=request.user.id)
|
|
t = ()
|
|
for i in taken_courses:
|
|
t += (i.course.pk,)
|
|
|
|
courses = (
|
|
Course.objects.filter(
|
|
program__pk=student.program.id,
|
|
level=student.level,
|
|
semester=current_semester,
|
|
)
|
|
.exclude(id__in=t)
|
|
.order_by("year")
|
|
)
|
|
all_courses = Course.objects.filter(
|
|
level=student.level, program__pk=student.program.id
|
|
)
|
|
|
|
no_course_is_registered = False # Check if no course is registered
|
|
all_courses_are_registered = False
|
|
|
|
registered_courses = Course.objects.filter(level=student.level).filter(id__in=t)
|
|
if (
|
|
registered_courses.count() == 0
|
|
): # Check if number of registered courses is 0
|
|
no_course_is_registered = True
|
|
|
|
if registered_courses.count() == all_courses.count():
|
|
all_courses_are_registered = True
|
|
|
|
total_first_semester_credit = 0
|
|
total_sec_semester_credit = 0
|
|
total_registered_credit = 0
|
|
for i in courses:
|
|
if i.semester == "First":
|
|
total_first_semester_credit += int(i.credit)
|
|
if i.semester == "Second":
|
|
total_sec_semester_credit += int(i.credit)
|
|
for i in registered_courses:
|
|
total_registered_credit += int(i.credit)
|
|
context = {
|
|
"is_calender_on": True,
|
|
"all_courses_are_registered": all_courses_are_registered,
|
|
"no_course_is_registered": no_course_is_registered,
|
|
"current_semester": current_semester,
|
|
"courses": courses,
|
|
"total_first_semester_credit": total_first_semester_credit,
|
|
"total_sec_semester_credit": total_sec_semester_credit,
|
|
"registered_courses": registered_courses,
|
|
"total_registered_credit": total_registered_credit,
|
|
"student": student,
|
|
}
|
|
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")
|