mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2025-01-01 10:02:01 +00:00
add create contest problem
This commit is contained in:
parent
e87c567f55
commit
0fdaab7e88
34
contest/migrations/0003_auto_20170217_0820.py
Normal file
34
contest/migrations/0003_auto_20170217_0820.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.12 on 2017-02-17 08:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contest', '0002_auto_20170209_0845'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
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.DeleteModel(
|
||||
name='ContestProblem',
|
||||
),
|
||||
]
|
@ -3,7 +3,6 @@ from django.utils.timezone import now
|
||||
from jsonfield import JSONField
|
||||
|
||||
from account.models import User
|
||||
from problem.models import AbstractProblem
|
||||
from utils.models import RichTextField
|
||||
|
||||
|
||||
@ -61,17 +60,6 @@ class Contest(models.Model):
|
||||
db_table = "contest"
|
||||
|
||||
|
||||
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"), )
|
||||
|
||||
|
||||
class ContestRank(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
contest = models.ForeignKey(Contest)
|
||||
|
63
problem/migrations/0003_auto_20170217_0820.py
Normal file
63
problem/migrations/0003_auto_20170217_0820.py
Normal file
@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.12 on 2017-02-17 08:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import jsonfield.fields
|
||||
import utils.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contest', '0003_auto_20170217_0820'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('problem', '0002_problem__id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ContestProblem',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=128)),
|
||||
('description', utils.models.RichTextField()),
|
||||
('input_description', utils.models.RichTextField()),
|
||||
('output_description', utils.models.RichTextField()),
|
||||
('samples', jsonfield.fields.JSONField()),
|
||||
('test_case_id', models.CharField(max_length=32)),
|
||||
('test_case_score', jsonfield.fields.JSONField()),
|
||||
('hint', utils.models.RichTextField(blank=True, null=True)),
|
||||
('languages', jsonfield.fields.JSONField()),
|
||||
('template', jsonfield.fields.JSONField()),
|
||||
('create_time', models.DateTimeField(auto_now_add=True)),
|
||||
('last_update_time', models.DateTimeField(blank=True, null=True)),
|
||||
('time_limit', models.IntegerField()),
|
||||
('memory_limit', models.IntegerField()),
|
||||
('spj', models.BooleanField(default=False)),
|
||||
('spj_language', models.CharField(blank=True, max_length=32, null=True)),
|
||||
('spj_code', models.TextField(blank=True, null=True)),
|
||||
('spj_version', models.CharField(blank=True, max_length=32, null=True)),
|
||||
('rule_type', models.CharField(max_length=32)),
|
||||
('visible', models.BooleanField(default=True)),
|
||||
('difficulty', models.CharField(max_length=32)),
|
||||
('source', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('total_submit_number', models.IntegerField(default=0)),
|
||||
('total_accepted_number', models.IntegerField(default=0)),
|
||||
('_id', models.CharField(db_index=True, max_length=24)),
|
||||
('is_public', models.BooleanField(default=False)),
|
||||
('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.Contest')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('tags', models.ManyToManyField(to='problem.ProblemTag')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'contest_problem',
|
||||
},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='contestproblem',
|
||||
unique_together=set([('_id', 'contest')]),
|
||||
),
|
||||
]
|
@ -2,6 +2,7 @@ from django.db import models
|
||||
from jsonfield import JSONField
|
||||
|
||||
from account.models import User
|
||||
from contest.models import Contest
|
||||
from utils.models import RichTextField
|
||||
|
||||
|
||||
@ -66,3 +67,14 @@ class AbstractProblem(models.Model):
|
||||
|
||||
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"), )
|
||||
|
@ -64,6 +64,10 @@ class EditProblemSerializer(CreateOrEditProblemSerializer):
|
||||
id = serializers.IntegerField()
|
||||
|
||||
|
||||
class CreateContestProblemSerializer(CreateOrEditProblemSerializer):
|
||||
contest_id = serializers.IntegerField()
|
||||
|
||||
|
||||
class TagSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ProblemTag
|
||||
|
@ -1,8 +1,9 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
from ..views.admin import ProblemAPI, TestCaseUploadAPI
|
||||
from ..views.admin import ProblemAPI, TestCaseUploadAPI, ContestProblemAPI
|
||||
|
||||
urlpatterns = [
|
||||
url(r"^test_case/upload$", TestCaseUploadAPI.as_view(), name="test_case_upload_api"),
|
||||
url(r"^problem$", ProblemAPI.as_view(), name="problem_api")
|
||||
url(r"^problem$", ProblemAPI.as_view(), name="problem_api"),
|
||||
url(r'contest/problem$', ContestProblemAPI.as_view(), name="contest_problem_api")
|
||||
]
|
||||
|
@ -6,12 +6,13 @@ import zipfile
|
||||
from django.conf import settings
|
||||
|
||||
from account.decorators import problem_permission_required
|
||||
from contest.models import Contest
|
||||
from utils.api import APIView, CSRFExemptAPIView, validate_serializer
|
||||
from utils.shortcuts import rand_str
|
||||
|
||||
from ..models import Problem, ProblemRuleType, ProblemTag
|
||||
from ..models import Problem, ProblemRuleType, ProblemTag, ContestProblem
|
||||
from ..serializers import (CreateProblemSerializer, EditProblemSerializer,
|
||||
ProblemSerializer, TestCaseUploadForm)
|
||||
ProblemSerializer, TestCaseUploadForm, CreateContestProblemSerializer)
|
||||
|
||||
|
||||
class TestCaseUploadAPI(CSRFExemptAPIView):
|
||||
@ -170,6 +171,9 @@ class ProblemAPI(APIView):
|
||||
problems = Problem.objects.all().order_by("-create_time")
|
||||
if not user.can_mgmt_all_problem():
|
||||
problems = problems.filter(created_by=request.user)
|
||||
keyword = request.GET.get("keyword")
|
||||
if keyword:
|
||||
problems = problems.filter(title__contains=keyword)
|
||||
return self.success(self.paginate_data(request, problems, ProblemSerializer))
|
||||
|
||||
@validate_serializer(EditProblemSerializer)
|
||||
@ -203,6 +207,7 @@ class ProblemAPI(APIView):
|
||||
else:
|
||||
data["spj_language"] = None
|
||||
data["spj_code"] = None
|
||||
|
||||
if data["rule_type"] == ProblemRuleType.OI:
|
||||
for item in data["test_case_score"]:
|
||||
if item["score"] <= 0:
|
||||
@ -223,3 +228,81 @@ class ProblemAPI(APIView):
|
||||
problem.tags.add(tag)
|
||||
|
||||
return self.success()
|
||||
|
||||
|
||||
class ContestProblemAPI(APIView):
|
||||
@validate_serializer(CreateContestProblemSerializer)
|
||||
def post(self, request):
|
||||
data = request.data
|
||||
|
||||
try:
|
||||
contest = Contest.objects.get(id=data.pop("contest_id"))
|
||||
if request.user.is_admin() and contest.created_by != request.user:
|
||||
return self.error("Contest does not exist")
|
||||
except Contest.DoesNotExist:
|
||||
return self.error("Contest does not exist")
|
||||
|
||||
if data["rule_type"] != contest.rule_type:
|
||||
return self.error("Invalid rule type")
|
||||
|
||||
_id = data["_id"]
|
||||
if not _id:
|
||||
return self.error("Display id is required for contest problem")
|
||||
try:
|
||||
ContestProblem.objects.get(_id=_id, contest=contest)
|
||||
return self.error("Duplicate Display id")
|
||||
except ContestProblem.DoesNotExist:
|
||||
pass
|
||||
|
||||
if data["spj"]:
|
||||
if not data["spj_language"] or not data["spj_code"]:
|
||||
return self.error("Invalid spj")
|
||||
data["spj_version"] = hashlib.md5((data["spj_language"] + ":" + data["spj_code"]).encode("utf-8")).hexdigest()
|
||||
else:
|
||||
data["spj_language"] = None
|
||||
data["spj_code"] = None
|
||||
|
||||
if data["rule_type"] == ProblemRuleType.OI:
|
||||
for item in data["test_case_score"]:
|
||||
if item["score"] <= 0:
|
||||
return self.error("Invalid score")
|
||||
# todo check filename and score info
|
||||
|
||||
data["created_by"] = request.user
|
||||
data["contest"] = contest
|
||||
tags = data.pop("tags")
|
||||
data["languages"] = list(data["languages"])
|
||||
|
||||
problem = ContestProblem.objects.create(**data)
|
||||
|
||||
for item in tags:
|
||||
try:
|
||||
tag = ProblemTag.objects.get(name=item)
|
||||
except ProblemTag.DoesNotExist:
|
||||
tag = ProblemTag.objects.create(name=item)
|
||||
problem.tags.add(tag)
|
||||
return self.success(ProblemSerializer(problem).data)
|
||||
|
||||
def get(self, request):
|
||||
problem_id = request.GET.get("id")
|
||||
contest_id = request.GET.get("contest_id")
|
||||
user = request.user
|
||||
if problem_id:
|
||||
try:
|
||||
problem = ContestProblem.objects.get(id=problem_id)
|
||||
if request.user.is_admin() and problem.contest.created_by != user:
|
||||
return self.error("Problem does not exist")
|
||||
except ContestProblem.DoesNotExist:
|
||||
return self.error("Problem does not exist")
|
||||
return self.success(ProblemSerializer(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")
|
||||
if user.is_admin():
|
||||
problems = problems.filter(contest__created_by=user)
|
||||
keyword = request.GET.get("keyword")
|
||||
if keyword:
|
||||
problems = problems.filter(title__contains=keyword)
|
||||
return self.success(self.paginate_data(request, problems, ProblemSerializer))
|
||||
|
Loading…
Reference in New Issue
Block a user