NDOJ/judge/models/course.py
2023-03-01 20:40:49 +07:00

184 lines
5 KiB
Python

from django.core.validators import RegexValidator
from django.db import models
from django.utils.translation import gettext, gettext_lazy as _
from judge.models import Contest
from judge.models.profile import Organization, Profile
__all__ = [
"Course",
"CourseRole",
"CourseResource",
"CourseAssignment",
]
course_directory_file = ""
class Course(models.Model):
name = models.CharField(
max_length=128,
verbose_name=_("course name"),
)
about = models.TextField(verbose_name=_("organization description"))
ending_time = models.DateTimeField(
verbose_name=_("ending time"),
)
is_public = models.BooleanField(
verbose_name=_("publicly visible"),
default=False,
)
organizations = models.ManyToManyField(
Organization,
blank=True,
verbose_name=_("organizations"),
help_text=_("If private, only these organizations may see the course"),
)
slug = models.SlugField(
max_length=128,
verbose_name=_("course slug"),
help_text=_("Course name shown in URL"),
unique=True,
validators=[
RegexValidator("^[-a-zA-Z0-9]+$", _("Only alphanumeric and hyphens"))
],
)
is_open = models.BooleanField(
verbose_name=_("public registration"),
default=False,
)
image_url = models.CharField(
verbose_name=_("course image"),
default="",
max_length=150,
blank=True,
)
def __str__(self):
return self.name
@classmethod
def is_editable_by(cls, course, profile):
userquery = CourseRole.objects.filter(course=course, user=profile)
if userquery.exists():
if userquery[0].role == "AS" or userquery[0].role == "TE":
return True
return False
@classmethod
def is_accessible_by(cls, course, profile):
userqueryset = CourseRole.objects.filter(course=course, user=profile)
if userqueryset.exists():
return True
else:
return False
@classmethod
def get_students(cls, course):
return CourseRole.objects.filter(course=course, role="ST").values("user")
@classmethod
def get_assistants(cls, course):
return CourseRole.objects.filter(course=course, role="AS").values("user")
@classmethod
def get_teachers(cls, course):
return CourseRole.objects.filter(course=course, role="TE").values("user")
@classmethod
def add_student(cls, course, profiles):
for profile in profiles:
CourseRole.make_role(course=course, user=profile, role="ST")
@classmethod
def add_teachers(cls, course, profiles):
for profile in profiles:
CourseRole.make_role(course=course, user=profile, role="TE")
@classmethod
def add_assistants(cls, course, profiles):
for profile in profiles:
CourseRole.make_role(course=course, user=profile, role="AS")
class CourseRole(models.Model):
course = models.ForeignKey(
Course,
verbose_name=_("course"),
on_delete=models.CASCADE,
db_index=True,
)
user = models.ForeignKey(
Profile,
verbose_name=_("user"),
on_delete=models.CASCADE,
related_name=_("user_of_course"),
)
class RoleInCourse(models.TextChoices):
STUDENT = "ST", _("Student")
ASSISTANT = "AS", _("Assistant")
TEACHER = "TE", _("Teacher")
role = models.CharField(
max_length=2,
choices=RoleInCourse.choices,
default=RoleInCourse.STUDENT,
)
@classmethod
def make_role(self, course, user, role):
userqueryset = CourseRole.objects.filter(course=course, user=user)
if userqueryset.exists():
userqueryset[0].role = role
else:
couresrole = CourseRole()
couresrole.course = course
couresrole.user = user
couresrole.role = role
couresrole.save()
class CourseResource(models.Model):
course = models.ForeignKey(
Course,
verbose_name=_("course"),
on_delete=models.CASCADE,
db_index=True,
)
files = models.FileField(
verbose_name=_("course files"),
null=True,
blank=True,
upload_to=course_directory_file,
)
description = models.CharField(
verbose_name=_("description"),
blank=True,
max_length=150,
)
order = models.IntegerField(null=True, default=None)
is_public = models.BooleanField(
verbose_name=_("publicly visible"),
default=False,
)
def __str__(self):
return f"Resource - {self.pk}"
class CourseAssignment(models.Model):
course = models.ForeignKey(
Course,
verbose_name=_("course"),
on_delete=models.CASCADE,
db_index=True,
)
contest = models.ForeignKey(
Contest,
verbose_name=_("contest"),
on_delete=models.CASCADE,
)
points = models.FloatField(
verbose_name=_("points"),
)