merge problem and contest_problem
This commit is contained in:
66
problem/migrations/0008_auto_20170923_1318.py
Normal file
66
problem/migrations/0008_auto_20170923_1318.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.4 on 2017-09-23 13:18
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contest', '0005_auto_20170823_0918'),
|
||||
('problem', '0006_auto_20170823_0918'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contestproblem',
|
||||
name='total_score',
|
||||
field=models.IntegerField(blank=True, default=0),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='problem',
|
||||
name='total_score',
|
||||
field=models.IntegerField(blank=True, default=0),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='contestproblem',
|
||||
unique_together=set([]),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='contestproblem',
|
||||
name='contest',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='contestproblem',
|
||||
name='created_by',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='contestproblem',
|
||||
name='tags',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='problem',
|
||||
name='contest',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contest.Contest'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='problem',
|
||||
name='is_public',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='problem',
|
||||
name='_id',
|
||||
field=models.CharField(db_index=True, max_length=24),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='problem',
|
||||
unique_together=set([('_id', 'contest')]),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='ContestProblem',
|
||||
),
|
||||
]
|
||||
@@ -24,7 +24,12 @@ class ProblemDifficulty(object):
|
||||
Low = "Low"
|
||||
|
||||
|
||||
class AbstractProblem(models.Model):
|
||||
class Problem(models.Model):
|
||||
# display ID
|
||||
_id = models.CharField(max_length=24, db_index=True)
|
||||
contest = models.ForeignKey(Contest, null=True, blank=True)
|
||||
# for contest problem
|
||||
is_public = models.BooleanField(default=False)
|
||||
title = models.CharField(max_length=128)
|
||||
# HTML
|
||||
description = RichTextField()
|
||||
@@ -33,6 +38,7 @@ class AbstractProblem(models.Model):
|
||||
# [{input: "test", output: "123"}, {input: "test123", output: "456"}]
|
||||
samples = JSONField()
|
||||
test_case_id = models.CharField(max_length=32)
|
||||
# [{"input_name": "1.in", "output_name": "1.out", "score": 0}]
|
||||
test_case_score = JSONField()
|
||||
hint = RichTextField(blank=True, null=True)
|
||||
languages = JSONField()
|
||||
@@ -55,6 +61,8 @@ class AbstractProblem(models.Model):
|
||||
difficulty = models.CharField(max_length=32)
|
||||
tags = models.ManyToManyField(ProblemTag)
|
||||
source = models.CharField(max_length=200, blank=True, null=True)
|
||||
# for OI mode
|
||||
total_score = models.IntegerField(default=0, blank=True)
|
||||
submission_number = models.BigIntegerField(default=0)
|
||||
accepted_number = models.BigIntegerField(default=0)
|
||||
# ACM rule_type: {JudgeStatus.ACCEPTED: 3, JudgeStaus.WRONG_ANSWER: 11}, the number means count
|
||||
@@ -62,7 +70,7 @@ class AbstractProblem(models.Model):
|
||||
|
||||
class Meta:
|
||||
db_table = "problem"
|
||||
abstract = True
|
||||
unique_together = (("_id", "contest"),)
|
||||
|
||||
def add_submission_number(self):
|
||||
self.submission_number = models.F("submission_number") + 1
|
||||
@@ -71,18 +79,3 @@ class AbstractProblem(models.Model):
|
||||
def add_ac_number(self):
|
||||
self.accepted_number = models.F("accepted_number") + 1
|
||||
self.save(update_fields=["accepted_number"])
|
||||
|
||||
|
||||
class Problem(AbstractProblem):
|
||||
_id = models.CharField(max_length=24, unique=True, db_index=True)
|
||||
|
||||
|
||||
class ContestProblem(AbstractProblem):
|
||||
_id = models.CharField(max_length=24, db_index=True)
|
||||
contest = models.ForeignKey(Contest)
|
||||
# 是否已经公开了题目,防止重复公开
|
||||
is_public = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
db_table = "contest_problem"
|
||||
unique_together = (("_id", "contest"),)
|
||||
|
||||
@@ -4,7 +4,6 @@ from judge.languages import language_names, spj_language_names
|
||||
from utils.api import DateTimeTZField, UsernameSerializer, serializers
|
||||
|
||||
from .models import Problem, ProblemRuleType, ProblemTag
|
||||
from .models import ContestProblem
|
||||
|
||||
|
||||
class TestCaseUploadForm(forms.Form):
|
||||
@@ -93,16 +92,16 @@ class ProblemAdminSerializer(BaseProblemSerializer):
|
||||
|
||||
class ContestProblemAdminSerializer(BaseProblemSerializer):
|
||||
class Meta:
|
||||
model = ContestProblem
|
||||
model = Problem
|
||||
|
||||
|
||||
class ProblemSerializer(BaseProblemSerializer):
|
||||
class Meta:
|
||||
model = Problem
|
||||
exclude = ("test_case_score", "test_case_id", "visible")
|
||||
exclude = ("contest", "test_case_score", "test_case_id", "visible", "is_public")
|
||||
|
||||
|
||||
class ContestProblemSerializer(BaseProblemSerializer):
|
||||
class Meta:
|
||||
model = ContestProblem
|
||||
model = Problem
|
||||
exclude = ("test_case_score", "test_case_id", "visible", "is_public")
|
||||
|
||||
@@ -10,11 +10,10 @@ from contest.models import Contest
|
||||
from utils.api import APIView, CSRFExemptAPIView, validate_serializer
|
||||
from utils.shortcuts import rand_str
|
||||
|
||||
from ..models import ContestProblem, Problem, ProblemRuleType, ProblemTag
|
||||
from ..serializers import (CreateContestProblemSerializer,
|
||||
from ..models import Problem, ProblemRuleType, ProblemTag
|
||||
from ..serializers import (CreateContestProblemSerializer, ContestProblemAdminSerializer,
|
||||
CreateProblemSerializer, EditProblemSerializer,
|
||||
ProblemAdminSerializer, TestCaseUploadForm,
|
||||
ContestProblemAdminSerializer)
|
||||
ProblemAdminSerializer, TestCaseUploadForm)
|
||||
|
||||
|
||||
class TestCaseUploadAPI(CSRFExemptAPIView):
|
||||
@@ -134,9 +133,13 @@ class ProblemAPI(APIView):
|
||||
data["spj_language"] = None
|
||||
data["spj_code"] = None
|
||||
if data["rule_type"] == ProblemRuleType.OI:
|
||||
total_score = 0
|
||||
for item in data["test_case_score"]:
|
||||
if item["score"] <= 0:
|
||||
return self.error("Invalid score")
|
||||
else:
|
||||
total_score += item["score"]
|
||||
data["total_score"] = total_score
|
||||
# todo check filename and score info
|
||||
data["created_by"] = request.user
|
||||
tags = data.pop("tags")
|
||||
@@ -211,9 +214,13 @@ class ProblemAPI(APIView):
|
||||
data["spj_code"] = None
|
||||
|
||||
if data["rule_type"] == ProblemRuleType.OI:
|
||||
total_score = 0
|
||||
for item in data["test_case_score"]:
|
||||
if item["score"] <= 0:
|
||||
return self.error("Invalid score")
|
||||
else:
|
||||
total_score += item["score"]
|
||||
data["total_score"] = total_score
|
||||
# todo check filename and score info
|
||||
tags = data.pop("tags")
|
||||
|
||||
@@ -250,11 +257,9 @@ class ContestProblemAPI(APIView):
|
||||
_id = data["_id"]
|
||||
if not _id:
|
||||
return self.error("Display id is required for contest problem")
|
||||
try:
|
||||
ContestProblem.objects.get(_id=_id, contest=contest)
|
||||
|
||||
if Problem.objects.filter(_id=_id, contest=contest).exists():
|
||||
return self.error("Duplicate Display id")
|
||||
except ContestProblem.DoesNotExist:
|
||||
pass
|
||||
|
||||
if data["spj"]:
|
||||
if not data["spj_language"] or not data["spj_code"]:
|
||||
@@ -275,7 +280,7 @@ class ContestProblemAPI(APIView):
|
||||
tags = data.pop("tags")
|
||||
data["languages"] = list(data["languages"])
|
||||
|
||||
problem = ContestProblem.objects.create(**data)
|
||||
problem = Problem.objects.create(**data)
|
||||
|
||||
for item in tags:
|
||||
try:
|
||||
@@ -291,17 +296,17 @@ class ContestProblemAPI(APIView):
|
||||
user = request.user
|
||||
if problem_id:
|
||||
try:
|
||||
problem = ContestProblem.objects.get(id=problem_id)
|
||||
problem = Problem.objects.get(id=problem_id)
|
||||
if user.is_admin() and problem.contest.created_by != user:
|
||||
return self.error("Problem does not exist")
|
||||
except ContestProblem.DoesNotExist:
|
||||
except Problem.DoesNotExist:
|
||||
return self.error("Problem does not exist")
|
||||
return self.success(ProblemAdminSerializer(problem).data)
|
||||
|
||||
if not contest_id:
|
||||
return self.error("Contest id is required")
|
||||
|
||||
problems = ContestProblem.objects.filter(contest_id=contest_id).order_by("-create_time")
|
||||
problems = Problem.objects.filter(contest_id=contest_id).order_by("-create_time")
|
||||
if user.is_admin():
|
||||
problems = problems.filter(contest__created_by=user)
|
||||
keyword = request.GET.get("keyword")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.db.models import Q
|
||||
from utils.api import APIView
|
||||
from account.decorators import check_contest_permission
|
||||
from ..models import ProblemTag, Problem, ContestProblem, ProblemRuleType
|
||||
from ..models import ProblemTag, Problem, ProblemRuleType
|
||||
from ..serializers import ProblemSerializer, TagSerializer
|
||||
from ..serializers import ContestProblemSerializer
|
||||
from contest.models import ContestRuleType
|
||||
@@ -66,14 +66,14 @@ class ContestProblemAPI(APIView):
|
||||
problem_id = request.GET.get("problem_id")
|
||||
if problem_id:
|
||||
try:
|
||||
problem = ContestProblem.objects.select_related("created_by").get(_id=problem_id, contest=self.contest,
|
||||
visible=True)
|
||||
except ContestProblem.DoesNotExist:
|
||||
problem = Problem.objects.select_related("created_by").get(_id=problem_id,
|
||||
contest=self.contest,
|
||||
visible=True)
|
||||
except Problem.DoesNotExist:
|
||||
return self.error("Problem does not exist.")
|
||||
return self.success(ContestProblemSerializer(problem).data)
|
||||
|
||||
contest_problems = ContestProblem.objects.select_related("created_by").filter(contest=self.contest,
|
||||
visible=True)
|
||||
contest_problems = Problem.objects.select_related("created_by").filter(contest=self.contest, visible=True)
|
||||
# 根据profile, 为做过的题目添加标记
|
||||
data = ContestProblemSerializer(contest_problems, many=True).data
|
||||
if request.user.id:
|
||||
|
||||
Reference in New Issue
Block a user