add course models

This commit is contained in:
zhaospei 2023-01-31 22:50:52 +07:00
parent b049f6eace
commit 51006bc773
4 changed files with 238 additions and 0 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,58 @@
# Generated by Django 3.2.16 on 2023-01-31 15:49
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('judge', '0147_alter_profile_timezone'),
]
operations = [
migrations.CreateModel(
name='Course',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('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(default=False, verbose_name='publicly visible')),
('slug', models.SlugField(help_text='Course name shown in URL', max_length=128, unique=True, validators=[django.core.validators.RegexValidator('^[-a-zA-Z0-9]+$', 'Only alphanumeric and hyphens')], verbose_name='course slug')),
('is_open', models.BooleanField(default=False, verbose_name='public registration')),
('image_url', models.CharField(blank=True, default='', max_length=150, verbose_name='course image')),
('organizations', models.ManyToManyField(blank=True, help_text='If private, only these organizations may see the course', to='judge.Organization', verbose_name='organizations')),
],
),
migrations.CreateModel(
name='CourseRole',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('role', models.CharField(choices=[('ST', 'Student'), ('AS', 'Assistant'), ('TE', 'Teacher')], default='ST', max_length=2)),
('course', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='judge.course', verbose_name='course')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_of_course', to='judge.profile', verbose_name='user')),
],
),
migrations.CreateModel(
name='CourseResource',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('files', models.FileField(blank=True, null=True, upload_to='', verbose_name='course files')),
('description', models.CharField(blank=True, max_length=150, verbose_name='description')),
('order', models.IntegerField(default=None, null=True)),
('is_public', models.BooleanField(default=False, verbose_name='publicly visible')),
('course', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='judge.course', verbose_name='course')),
],
),
migrations.CreateModel(
name='CourseAssignment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('points', models.FloatField(verbose_name='points')),
('contest', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='judge.contest', verbose_name='contest')),
('course', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='judge.course', verbose_name='course')),
],
),
]

View file

@ -56,6 +56,7 @@ from judge.models.ticket import Ticket, TicketMessage
from judge.models.volunteer import VolunteerProblemVote from judge.models.volunteer import VolunteerProblemVote
from judge.models.pagevote import PageVote, PageVoteVoter from judge.models.pagevote import PageVote, PageVoteVoter
from judge.models.bookmark import BookMark, MakeBookMark from judge.models.bookmark import BookMark, MakeBookMark
from judge.models.course import Course
revisions.register(Profile, exclude=["points", "last_access", "ip", "rating"]) revisions.register(Profile, exclude=["points", "last_access", "ip", "rating"])
revisions.register(Problem, follow=["language_limits"]) revisions.register(Problem, follow=["language_limits"])
@ -81,4 +82,5 @@ revisions.register(Rating)
revisions.register(PageVoteVoter) revisions.register(PageVoteVoter)
revisions.register(VolunteerProblemVote) revisions.register(VolunteerProblemVote)
revisions.register(MakeBookMark) revisions.register(MakeBookMark)
revisions.register(Course)
del revisions del revisions

160
judge/models/course.py Normal file
View file

@ -0,0 +1,160 @@
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(course, profile):
if (profile.is_superuser):
return True
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(course, profile):
userqueryset = CourseRole.objects.filter(course=course, user=profile)
if userqueryset.exists():
return True
else:
return False
@classmethod
def get_students(course):
return CourseRole.objects.filter(course=course, role='ST').values('user')
@classmethod
def get_assistants(course):
return CourseRole.objects.filter(course=course, role='AS').values('user')
@classmethod
def get_teachers(course):
return CourseRole.objects.filter(course=course, role='TE').values('user')
@classmethod
def add_student(course, profiles):
for profile in profiles:
CourseRole.make_role(course=course, user=profile, role='ST')
@classmethod
def add_teachers(course, profiles):
for profile in profiles:
CourseRole.make_role(course=course, user=profile, role='TE')
@classmethod
def add_assistants(course, profiles):
for profile in profiles:
CourseRole.make_role(course=course, user=profile, role='AS')
class CourseRole(models.Model):
course = models.OneToOneField(
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.OneToOneField(
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,)
class CourseAssignment(models.Model):
course = models.OneToOneField(
Course,
verbose_name=_("course"),
on_delete=models.CASCADE,
db_index=True,
)
contest = models.OneToOneField(
Contest,
verbose_name=_("contest"),
on_delete=models.CASCADE,
)
points = models.FloatField(verbose_name=_("points"),)