class Submission(models.Model): id = models.TextField(default=rand_str, primary_key=True, db_index=True) contest = models.ForeignKey(Contest, null=True) problem = models.ForeignKey(Problem) create_time = models.DateTimeField(auto_now_add=True) user_id = models.IntegerField(db_index=True) username = models.TextField() code = models.TextField() result = models.IntegerField(db_index=True, default=JudgeStatus.PENDING) # 从JudgeServer返回的判题详情 info = JSONField(default=dict) language = models.TextField() shared = models.BooleanField(default=False) # 存储该提交所用时间和内存值,方便提交列表显示 # {time_cost: "", memory_cost: "", err_info: "", score: 0} statistic_info = JSONField(default=dict) ip = models.TextField(null=True) def check_user_permission(self, user, check_share=True): return self.user_id == user.id or \ (check_share and self.shared is True) or \ user.is_super_admin() or \ user.can_mgmt_all_problem() or \ self.problem.created_by_id == user.id class Meta: db_table = "submission" ordering = ("-create_time",) def __str__(self): return self.id
class Problem(models.Model): # display ID _id = models.TextField(db_index=True) contest = models.ForeignKey(Contest, null=True) # for contest problem is_public = models.BooleanField(default=False) title = models.TextField() # HTML description = RichTextField() input_description = RichTextField() output_description = RichTextField() # [{input: "test", output: "123"}, {input: "test123", output: "456"}] samples = JSONField() test_case_id = models.TextField() # [{"input_name": "1.in", "output_name": "1.out", "score": 0}] test_case_score = JSONField() hint = RichTextField(null=True) languages = JSONField() template = JSONField() create_time = models.DateTimeField(auto_now_add=True) pe_ignored = models.BooleanField(default=False) # we can not use auto_now here last_update_time = models.DateTimeField(null=True) created_by = models.ForeignKey(User) # ms time_limit = models.IntegerField() # MB memory_limit = models.IntegerField() # special judge related spj = models.BooleanField(default=False) spj_language = models.TextField(null=True) spj_code = models.TextField(null=True) spj_version = models.TextField(null=True) spj_compile_ok = models.BooleanField(default=False) rule_type = models.TextField() visible = models.BooleanField(default=True) difficulty = models.TextField() tags = models.ManyToManyField(ProblemTag) source = models.TextField(null=True) # for OI mode total_score = models.IntegerField(default=0) submission_number = models.BigIntegerField(default=0) accepted_number = models.BigIntegerField(default=0) # {JudgeStatus.ACCEPTED: 3, JudgeStaus.WRONG_ANSWER: 11}, the number means count statistic_info = JSONField(default=dict) class Meta: db_table = "problem" unique_together = (("_id", "contest"),) ordering = ("_id",) def add_submission_number(self): self.submission_number = models.F("submission_number") + 1 self.save(update_fields=["submission_number"]) def add_ac_number(self): self.accepted_number = models.F("accepted_number") + 1 self.save(update_fields=["accepted_number"])
class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # print("1" + str(classNum)) # acm_problems_status examples: # { # "problems": { # "1": { # "status": JudgeStatus.ACCEPTED, # "_id": "1000" # } # }, # "contest_problems": { # "1": { # "status": JudgeStatus.ACCEPTED, # "_id": "1000" # } # } # } acm_problems_status = JSONField(default=dict) # like acm_problems_status, merely add "score" field oi_problems_status = JSONField(default=dict) real_name = models.TextField(null=True) avatar = models.TextField( default=f"{settings.AVATAR_URI_PREFIX}/default.png") blog = models.URLField(null=True) mood = models.TextField(null=True) github = models.TextField(null=True) school = models.TextField(null=True) classNum = models.TextField(null=True) major = models.TextField(null=True) # changed language = models.TextField(null=True) # for ACM accepted_number = models.IntegerField(default=0) # for OI total_score = models.BigIntegerField(default=0) submission_number = models.IntegerField(default=0) def add_accepted_problem_number(self): self.accepted_number = models.F("accepted_number") + 1 self.save() def add_submission_number(self): self.submission_number = models.F("submission_number") + 1 self.save() # 计算总分时, 应先减掉上次该题所得分数, 然后再加上本次所得分数 def add_score(self, this_time_score, last_time_score=None): last_time_score = last_time_score or 0 self.total_score = models.F( "total_score") - last_time_score + this_time_score self.save() class Meta: db_table = "user_profile"
class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # acm_problems_status examples: # { # "problems": { # "1": { # "status": JudgeStatus.ACCEPTED, # "_id": "1000" # } # }, # "contest_problems": { # "1": { # "status": JudgeStatus.ACCEPTED, # "_id": "1000" # } # } # } acm_problems_status = JSONField(default=dict) # like acm_problems_status, merely add "score" field oi_problems_status = JSONField(default=dict) real_name = models.TextField(null=True) avatar = models.TextField( default=f"{settings.AVATAR_URI_PREFIX}/default.png") blog = models.URLField(null=True) mood = models.TextField(null=True) github = models.TextField(null=True) school = models.TextField(null=True) major = models.TextField(null=True) language = models.TextField(null=True) # for ACM accepted_number = models.IntegerField(default=0) # for OI total_score = models.BigIntegerField(default=0) submission_number = models.IntegerField(default=0) def add_accepted_problem_number(self): self.accepted_number = models.F("accepted_number") + 1 self.save() def add_submission_number(self): self.submission_number = models.F("submission_number") + 1 self.save() # When calculating the total score, you should first subtract the score from the previous question, # and then add the score this time def add_score(self, this_time_score, last_time_score=None): last_time_score = last_time_score or 0 self.total_score = models.F( "total_score") - last_time_score + this_time_score self.save() class Meta: db_table = "user_profile"
class Contest(models.Model): title = models.TextField() description = RichTextField() # show real time rank or cached rank real_time_rank = models.BooleanField() password = models.TextField(null=True) # enum of ContestRuleType rule_type = models.TextField() start_time = models.DateTimeField() end_time = models.DateTimeField() create_time = models.DateTimeField(auto_now_add=True) last_update_time = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(User, on_delete=models.CASCADE) # 是否可见 false的话相当于删除 visible = models.BooleanField(default=True) allowed_ip_ranges = JSONField(default=list) similarity_check_result = JSONField(default=list) @property def status(self): if self.start_time > now(): # 没有开始 返回1 return ContestStatus.CONTEST_NOT_START elif self.end_time < now(): # 已经结束 返回-1 return ContestStatus.CONTEST_ENDED else: # 正在进行 返回0 return ContestStatus.CONTEST_UNDERWAY @property def contest_type(self): if self.password: return ContestType.PASSWORD_PROTECTED_CONTEST return ContestType.PUBLIC_CONTEST # 是否有权查看problem 的一些统计信息 诸如submission_number, accepted_number 等 def problem_details_permission(self, user): return self.rule_type == ContestRuleType.ACM or \ self.status == ContestStatus.CONTEST_ENDED or \ user.is_authenticated and user.is_contest_admin(self) or \ self.real_time_rank class Meta: db_table = "contest" ordering = ("-start_time", )
class OIContestRank(AbstractContestRank): total_score = models.IntegerField(default=0) # {"23": 333} # key is problem id, value is current score submission_info = JSONField(default=dict) class Meta: db_table = "oi_contest_rank"
class ACMContestRank(AbstractContestRank): accepted_number = models.IntegerField(default=0) # total_time is only for ACM contest, total_time = ac time + none-ac times * 20 * 60 total_time = models.IntegerField(default=0) # {"23": {"is_ac": True, "ac_time": 8999, "error_number": 2, "is_first_ac": True}} # key is problem id submission_info = JSONField(default=dict) class Meta: db_table = "acm_contest_rank"
class User(AbstractBaseUser): username = models.TextField(unique=True) email = models.TextField(null=True) create_time = models.DateTimeField(auto_now_add=True, null=True) # 用户所属学校 school = models.ForeignKey(School, models.CASCADE, null=True, blank=True) # student or teacher role_type = models.TextField(default=RoleType.STUDENT) # One of UserType admin_type = models.TextField(default=AdminType.REGULAR_USER) problem_permission = models.TextField(default=ProblemPermission.NONE) reset_password_token = models.TextField(null=True) reset_password_token_expire_time = models.DateTimeField(null=True) # SSO auth token auth_token = models.TextField(null=True) two_factor_auth = models.BooleanField(default=False) tfa_token = models.TextField(null=True) session_keys = JSONField(default=list) # open api key open_api = models.BooleanField(default=False) open_api_appkey = models.TextField(null=True) is_disabled = models.BooleanField(default=False) USERNAME_FIELD = "username" REQUIRED_FIELDS = [] objects = UserManager() def is_admin(self): return self.admin_type == AdminType.ADMIN def is_super_admin(self): return self.admin_type == AdminType.SUPER_ADMIN def is_admin_role(self): return self.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN] def is_teacher_role(self): return self.role_type in [RoleType.TEACHER] def can_mgmt_all_problem(self): return self.problem_permission == ProblemPermission.ALL def is_contest_admin(self, contest): return self.is_authenticated and (contest.created_by == self or self.admin_type == AdminType.SUPER_ADMIN) def save(self, *args, **kwargs): if not (self.role_type in [RoleType.TEACHER, RoleType.STUDENT]): raise ValidationError('role_type参数错误!') super().save(*args, **kwargs) class Meta: db_table = "user"
class LevelTestProblem(models.Model): title = models.TextField() description = RichTextField() answer = models.IntegerField() # 1~5 숫자중 하나 choices = JSONField() # key: 1~5 / value: 선택지 ordering = models.IntegerField() difficulty = models.TextField() class Meta: db_table = 'level_test_problem'
class User(AbstractBaseUser): username = models.TextField(unique=True) email = models.TextField(null=True) create_time = models.DateTimeField(auto_now_add=True, null=True) # One of UserType admin_type = models.TextField(default=AdminType.REGULAR_USER) problem_permission = models.TextField(default=ProblemPermission.NONE) reset_password_token = models.TextField(null=True) reset_password_token_expire_time = models.DateTimeField(null=True) # SSO auth token auth_token = models.TextField(null=True) two_factor_auth = models.BooleanField(default=False) tfa_token = models.TextField(null=True) session_keys = JSONField(default=list) # open api key open_api = models.BooleanField(default=False) open_api_appkey = models.TextField(null=True) is_disabled = models.BooleanField(default=False) # Sigh in last_sighin_time = models.DateField(default="1970-01-01") continue_sighin_days = models.IntegerField(default=0) # Title Call On title = models.TextField(null=True) title_color = models.TextField(null=True) USERNAME_FIELD = "username" REQUIRED_FIELDS = [] objects = UserManager() def is_admin(self): return self.admin_type == AdminType.ADMIN def is_super_admin(self): return self.admin_type == AdminType.SUPER_ADMIN def is_admin_role(self): return self.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN] def can_mgmt_all_problem(self): return self.problem_permission == ProblemPermission.ALL def is_contest_admin(self, contest): return self.is_authenticated and (contest.created_by == self or self.admin_type == AdminType.SUPER_ADMIN) def sighin_time(self): return self.last_sighin_time def continue_days(self): return self.continue_sighin_days class Meta: db_table = "user"
class User(AbstractBaseUser): """ 扩展 AbstractBaseUser 和 AbstractUser 的区别: AbstractBaseUser 只提供三个属性: 1. password 2. last_login 3. is_active 扩展的 AbstractBaseUser 必须指定 USERNAME_FIELD, REQUIRED_FIELDS USERNAME_FIELD 必须设置。 设置认证标识,设置成标识的字段 unique=True REQUIRED_FIELDS 必须设置。当通过createsuperuser管理命令创建一个用户时,用于提示的一个字段名称列表。 """ username = models.TextField(unique=True) email = models.TextField(null=True) create_time = models.DateTimeField(auto_now_add=True, null=True) # One of UserType admin_type = models.TextField(default=AdminType.REGULAR_USER) problem_permission = models.TextField(default=ProblemPermission.NONE) reset_password_token = models.TextField(null=True) reset_password_token_expire_time = models.DateTimeField(null=True) # SSO auth token auth_token = models.TextField(null=True) two_factor_auth = models.BooleanField(default=False) tfa_token = models.TextField(null=True) session_keys = JSONField(default=list) # open api key open_api = models.BooleanField(default=False) open_api_appkey = models.TextField(null=True) is_disabled = models.BooleanField(default=False) USERNAME_FIELD = "username" REQUIRED_FIELDS = [] objects = UserManager() def is_admin(self): return self.admin_type == AdminType.ADMIN def is_super_admin(self): return self.admin_type == AdminType.SUPER_ADMIN def is_admin_role(self): return self.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN] def can_mgmt_all_problem(self): return self.problem_permission == ProblemPermission.ALL def is_contest_admin(self, contest): return self.is_authenticated and (contest.created_by == self or self.admin_type == AdminType.SUPER_ADMIN) class Meta: db_table = "user"
class User(AbstractBaseUser): username = models.TextField(unique=True) email = models.TextField(null=True) create_time = models.DateTimeField(auto_now_add=True, null=True) in_class = models.ForeignKey('Class', null=True, on_delete=models.DO_NOTHING) paid = models.BooleanField(default=False) # One of UserType admin_type = models.TextField(default=AdminType.REGULAR_USER) problem_permission = models.TextField(default=ProblemPermission.NONE) reset_password_token = models.TextField(null=True) reset_password_token_expire_time = models.DateTimeField(null=True) # SSO auth token auth_token = models.TextField(null=True) two_factor_auth = models.BooleanField(default=False) tfa_token = models.TextField(null=True) session_keys = JSONField(default=list) # open api key open_api = models.BooleanField(default=False) open_api_appkey = models.TextField(null=True) is_disabled = models.BooleanField(default=False) USERNAME_FIELD = "username" REQUIRED_FIELDS = [] objects = UserManager() def is_admin(self): return self.admin_type == AdminType.ADMIN def is_super_admin(self): return self.admin_type == AdminType.SUPER_ADMIN def is_admin_role(self): return self.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN] def can_mgmt_all_problem(self): return self.problem_permission == ProblemPermission.ALL def is_contest_admin(self, contest): return self.is_authenticated and (contest.created_by == self or self.admin_type == AdminType.SUPER_ADMIN) def set_paid(self, paid): self.paid = paid self.save() class Meta: db_table = "user"
class Submission(models.Model): id = models.TextField(default=rand_str, primary_key=True, db_index=True) contest = models.ForeignKey(Contest, null=True, on_delete=models.CASCADE) problem = models.ForeignKey(Problem, on_delete=models.CASCADE) create_time = models.DateTimeField(auto_now_add=True) user_id = models.IntegerField(db_index=True) username = models.TextField() code = models.TextField() result = models.IntegerField(db_index=True, default=JudgeStatus.PENDING) # Judgment details returned from JudgeServer info = JSONField(default=dict) language = models.TextField() shared = models.BooleanField(default=False) # Store the time and memory value of the submission to facilitate the submission list display # {time_cost: "", memory_cost: "", err_info: "", score: 0} statistic_info = JSONField(default=dict) ip = models.TextField(null=True) def check_user_permission(self, user, check_share=True): if self.user_id == user.id or user.is_super_admin( ) or user.can_mgmt_all_problem( ) or self.problem.created_by_id == user.id: return True if check_share: if self.contest and self.contest.status != ContestStatus.CONTEST_ENDED: return False if self.problem.share_submission or self.shared: return True return False class Meta: db_table = "submission" ordering = ("-create_time", ) def __str__(self): return self.id
class Contest(models.Model): _id = models.TextField(db_index=True) title = models.TextField() description = RichTextField() # show real time rank or cached rank real_time_rank = models.BooleanField() password = models.TextField(null=True) # enum of ContestRuleType rule_type = models.TextField() start_time = models.DateTimeField() end_time = models.DateTimeField() create_time = models.DateTimeField(auto_now_add=True) last_update_time = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(User, on_delete=models.CASCADE) # ���閫� false���敶�� visible = models.BooleanField(default=True) allowed_ip_ranges = JSONField(default=list) @property def status(self): if self.start_time > now(): # 瘝⊥��憪� 餈��1 return ContestStatus.CONTEST_NOT_START elif self.end_time < now(): # 撌脩���� 餈��-1 return ContestStatus.CONTEST_ENDED else: # 甇��餈�� 餈��0 return ContestStatus.CONTEST_UNDERWAY @property def contest_type(self): if self.password: return ContestType.PASSWORD_PROTECTED_CONTEST return ContestType.PUBLIC_CONTEST # �������roblem ���鈭�恣靽⊥ 霂詨�ubmission_number, accepted_number 蝑� def problem_details_permission(self, user): return self.rule_type == ContestRuleType.ACM or \ self.status == ContestStatus.CONTEST_ENDED or \ user.is_authenticated and user.is_contest_admin(self) or \ self.real_time_rank class Meta: db_table = "contest" ordering = ("-start_time", )
class Contest(models.Model): title = models.TextField() description = RichTextField() # show real time rank or cached rank real_time_rank = models.BooleanField() password = models.TextField(null=True) # enum of ContestRuleType rule_type = models.TextField() start_time = models.DateTimeField() end_time = models.DateTimeField() create_time = models.DateTimeField(auto_now_add=True) last_update_time = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(User, on_delete=models.CASCADE) # If it is visible, false is equivalent to delete visible = models.BooleanField(default=True) allowed_ip_ranges = JSONField(default=list) @property def status(self): if self.start_time > now(): # NOT_START return 1 return ContestStatus.CONTEST_NOT_START elif self.end_time < now(): # ENDED return -1 return ContestStatus.CONTEST_ENDED else: # UNDERWAY return 0 return ContestStatus.CONTEST_UNDERWAY @property def contest_type(self): if self.password: return ContestType.PASSWORD_PROTECTED_CONTEST return ContestType.PUBLIC_CONTEST # The permission to view some statistics of the problem, such as submission_number, accepted_number, etc. def problem_details_permission(self, user): return self.rule_type == ContestRuleType.ACM or \ self.status == ContestStatus.CONTEST_ENDED or \ user.is_authenticated and user.is_contest_admin(self) or \ self.real_time_rank class Meta: db_table = "contest" ordering = ("-start_time", )
class SysOptions(models.Model): key = models.TextField(unique=True, db_index=True) value = JSONField()
class SysOptions(models.Model): key = models.CharField(max_length=128, unique=True, db_index=True) value = JSONField()
class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # acm_problems_status examples: # { # "problems": { # "1": { # "status": JudgeStatus.ACCEPTED, # "_id": "1000" # } # }, # "contest_problems": { # "1": { # "status": JudgeStatus.ACCEPTED, # "_id": "1000" # } # } # } # 백준, 해커랭크 아이디 필드 추가 hr_username = models.TextField(null=True) bj_username = models.TextField(null=True) level = models.ForeignKey('problem.QuriousDifficulty', null=True, related_name='users', on_delete=models.CASCADE) current_reco = ArrayField(models.IntegerField(), default=list) recommend_round = models.IntegerField(default=0) # current_recommend = JSONField(default={'data'}, null=True) acm_problems_status = JSONField(default=dict) # like acm_problems_status, merely add "score" field oi_problems_status = JSONField(default=dict) real_name = models.TextField(null=True) avatar = models.TextField( default=f"{settings.AVATAR_URI_PREFIX}/default.png") blog = models.URLField(null=True) mood = models.TextField(null=True) github = models.TextField(null=True) school = models.TextField(null=True) major = models.TextField(null=True) language = models.TextField(null=True) # for ACM accepted_number = models.IntegerField(default=0) # for OI total_score = models.BigIntegerField(default=0) submission_number = models.IntegerField(default=0) def add_accepted_problem_number(self): self.accepted_number = models.F("accepted_number") + 1 self.save() def add_submission_number(self): self.submission_number = models.F("submission_number") + 1 self.save() # 计算总分时, 应先减掉上次该题所得分数, 然后再加上本次所得分数 def add_score(self, this_time_score, last_time_score=None): last_time_score = last_time_score or 0 self.total_score = models.F( "total_score") - last_time_score + this_time_score self.save() class Meta: db_table = "user_profile"