Add contest to course (#126)

This commit is contained in:
Phuoc Anh Kha Le 2024-10-02 15:06:33 -05:00 committed by GitHub
parent 72eada0a4e
commit 3d67fb274e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 1258 additions and 433 deletions

View file

@ -61,7 +61,13 @@ from judge.models.ticket import Ticket, TicketMessage
from judge.models.volunteer import VolunteerProblemVote
from judge.models.pagevote import PageVote, PageVoteVoter
from judge.models.bookmark import BookMark, MakeBookMark
from judge.models.course import Course, CourseRole, CourseLesson, CourseLessonProblem
from judge.models.course import (
Course,
CourseRole,
CourseLesson,
CourseLessonProblem,
CourseContest,
)
from judge.models.notification import Notification, NotificationProfile
from judge.models.test_formatter import TestFormatterModel

View file

@ -246,6 +246,10 @@ class Contest(models.Model, PageVotable, Bookmarkable):
verbose_name=_("organizations"),
help_text=_("If private, only these organizations may see the contest"),
)
is_in_course = models.BooleanField(
verbose_name=_("contest in course"),
default=False,
)
og_image = models.CharField(
verbose_name=_("OpenGraph image"), default="", max_length=150, blank=True
)
@ -561,6 +565,14 @@ class Contest(models.Model, PageVotable, Bookmarkable):
if not self.is_visible:
raise self.Inaccessible()
if self.is_in_course:
from judge.models import Course, CourseContest
course_contest = CourseContest.objects.filter(contest=self).first()
if Course.is_accessible_by(course_contest.course, user.profile):
return
raise self.Inaccessible()
# Contest is not private
if not self.is_private and not self.is_organization_private:
return
@ -612,7 +624,10 @@ class Contest(models.Model, PageVotable, Bookmarkable):
if not user.is_authenticated:
return (
cls.objects.filter(
is_visible=True, is_organization_private=False, is_private=False
is_visible=True,
is_organization_private=False,
is_private=False,
is_in_course=False,
)
.defer("description")
.distinct()
@ -626,7 +641,7 @@ class Contest(models.Model, PageVotable, Bookmarkable):
)
or show_own_contests_only
):
q = Q(is_visible=True)
q = Q(is_visible=True, is_in_course=False)
q &= (
Q(view_contest_scoreboard=user.profile)
| Q(is_organization_private=False, is_private=False)

View file

@ -4,7 +4,7 @@ from django.utils.translation import gettext, gettext_lazy as _
from django.urls import reverse
from django.db.models import Q
from judge.models import BlogPost, Problem
from judge.models import BlogPost, Problem, Contest
from judge.models.profile import Organization, Profile
@ -160,10 +160,11 @@ class CourseLesson(models.Model):
related_name="lessons",
on_delete=models.CASCADE,
)
title = models.TextField(verbose_name=_("course title"))
content = models.TextField(verbose_name=_("course content"))
title = models.TextField(verbose_name=_("lesson title"))
content = models.TextField(verbose_name=_("lesson content"))
order = models.IntegerField(verbose_name=_("order"), default=0)
points = models.IntegerField(verbose_name=_("points"))
is_visible = models.BooleanField(verbose_name=_("publicly visible"), default=True)
def get_absolute_url(self):
return reverse(
@ -182,3 +183,19 @@ class CourseLessonProblem(models.Model):
problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
order = models.IntegerField(verbose_name=_("order"), default=0)
score = models.IntegerField(verbose_name=_("score"), default=0)
class CourseContest(models.Model):
course = models.ForeignKey(
Course, on_delete=models.CASCADE, related_name="contests"
)
contest = models.ForeignKey(
Contest, unique=True, on_delete=models.CASCADE, related_name="course"
)
order = models.IntegerField(verbose_name=_("order"), default=0)
points = models.IntegerField(verbose_name=_("points"))
def get_course_of_contest(contest):
course_contest = contest.course.get()
course = course_contest.course
return course