From 937c382b2590c4177caaedf09164a49932cdf162 Mon Sep 17 00:00:00 2001 From: hohoTT <609029365@qq.com> Date: Tue, 18 Aug 2015 14:59:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E6=AF=94=E8=B5=9B=E5=92=8C?= =?UTF-8?q?=E6=AF=94=E8=B5=9B=E9=A2=98=E7=9B=AE=E7=9A=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=EF=BC=8C=E8=BF=98=E6=9C=89=E8=A6=81=E5=A2=9E=E5=8A=A0=E5=92=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9A=84=E5=9C=B0=E6=96=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/serializers.py | 95 +++++++++++++++++++++++ contest/views.py | 169 ++++++++++++++++++++++++++++++++++++++++- problem/models.py | 4 +- problem/tests.py | 5 ++ 4 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 contest/serializers.py diff --git a/contest/serializers.py b/contest/serializers.py new file mode 100644 index 00000000..424ba0ef --- /dev/null +++ b/contest/serializers.py @@ -0,0 +1,95 @@ +# coding=utf-8 +import json +from rest_framework import serializers + +from account.models import User +from .models import Contest, ContestProblem + + +class CreateContestSerializer(serializers.Serializer): + title = serializers.CharField(max_length=40) + description = serializers.CharField(max_length=5000) + mode = serializers.IntegerField() + show_rank = serializers.BooleanField() + password = serializers.CharField(max_length=30, required=False) + start_time = serializers.DateTimeField() + end_time = serializers.DateTimeField() + + +class ContestSerializer(serializers.ModelSerializer): + class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ["username"] + + created_by = UserSerializer() + + class Meta: + model = Contest + + +class EditContestSerializer(serializers.Serializer): + title = serializers.CharField(max_length=40) + description = serializers.CharField(max_length=10000) + mode = serializers.IntegerField() + show_rank = serializers.BooleanField() + password = serializers.CharField(max_length=30, required=False) + start_time = serializers.DateTimeField() + end_time = serializers.DateTimeField() + + +class ContestProblemSampleSerializer(serializers.ListField): + input = serializers.CharField(max_length=3000) + output = serializers.CharField(max_length=3000) + + +class JSONField(serializers.Field): + def to_representation(self, value): + return json.loads(value) + + +class CreateContestProblemSerializer(serializers.Serializer): + title = serializers.CharField(max_length=50) + description = serializers.CharField(max_length=10000) + input_description = serializers.CharField(max_length=10000) + output_description = serializers.CharField(max_length=10000) + # [{"input": "1 1", "output": "2"}] + samples = ContestProblemSampleSerializer() + test_case_id = serializers.CharField(max_length=40) + time_limit = serializers.IntegerField() + memory_limit = serializers.IntegerField() + difficulty = serializers.IntegerField() + hint = serializers.CharField(max_length=3000, allow_blank=True) + sort_index = serializers.CharField(max_length=30) + + +class ContestProblemSerializer(serializers.ModelSerializer): + samples = JSONField() + + class ContestSerializer(serializers.ModelSerializer): + class Meta: + model = Contest + fields = ["title"] + + created_by = ContestSerializer() + + class Meta: + model = ContestProblem + + +class EditContestProblemSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField(max_length=50) + description = serializers.CharField(max_length=10000) + input_description = serializers.CharField(max_length=10000) + output_description = serializers.CharField(max_length=10000) + test_case_id = serializers.CharField(max_length=40) + time_limit = serializers.IntegerField() + memory_limit = serializers.IntegerField() + difficulty = serializers.IntegerField() + samples = ContestProblemSampleSerializer() + hint = serializers.CharField(max_length=3000, allow_blank=True) + visible = serializers.BooleanField() + sort_index = serializers.CharField(max_length=30) + + diff --git a/contest/views.py b/contest/views.py index 91ea44a2..3746b2bf 100644 --- a/contest/views.py +++ b/contest/views.py @@ -1,3 +1,170 @@ +# coding=utf-8 +import json from django.shortcuts import render +from django.db import IntegrityError +from django.db.models import Q +from rest_framework.views import APIView -# Create your views here. +from .models import Contest, ContestProblem +from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer, + CreateContestProblemSerializer, ContestProblemSerializer, EditContestProblemSerializer) +from utils.shortcuts import (serializer_invalid_response, error_response, + success_response, paginate, rand_str, error_page) + + +def contest_page(request, contest_id): + pass + + +class ContestAdminAPIView(APIView): + def post(self, request): + """ + 比赛发布json api接口 + --- + request_serializer: CreateContestSerializer + response_serializer: ContestSerializer + """ + serializer = CreateContestSerializer(data=request.data) + if serializer.is_valid(): + data = serializer.data + try: + contest = Contest.objects.create(title=data["title"], description=data["description"], + mode=data["mode"], show_rank=data["show_rank"], + start_time=["start_time"], end_time=data["end_time"]) + if data["password"]: + contest.setpassword(data["password"]) + contest.save() + except IntegrityError: + return error_response(u"比赛名已经存在") + return success_response(ContestSerializer(contest).data) + else: + serializer_invalid_response(serializer) + + def put(self, request): + """ + 比赛编辑json api接口 + --- + request_serializer: EditContestSerializer + response_serializer: ContestSerializer + """ + serializer = EditContestSerializer(data=request.data) + if serializer.is_valid(): + data = serializer.data + try: + contest = Contest.objects.get(id=data["id"]) + except Contest.DoesNotExist: + error_response(u"该比赛不存在!") + try: + contest.title = data["contest"] + contest.description = data["description"] + contest.mode = data["mode"] + contest.show_rank = data["show_"] + if data["password"]: + contest.set_password(data["password"]) + contest.save() + except IntegrityError: + return error_response(u"比赛名已经存在") + + return success_response(ContestSerializer(contest).data) + else: + serializer_invalid_response(serializer) + + def get(self, request): + """ + 比赛分页json api接口 + --- + response_serializer: ContestSerializer + """ + contest = Contest.objects.all().order_by("-last_updated_time") + visible = request.GET.get("visible", None) + if visible: + contest = contest.filter(visible=(visible == "true")) + keyword = request.GET.get("keyword", None) + if keyword: + contest = contest.filter(Q(title__contains=keyword) | + Q(description__contains=keyword)) + return paginate(request, contest, ContestSerializer) + + +class ContestProblemAdminAPIView(APIView): + def post(self, request): + """ + 比赛题目发布json api接口 + --- + request_serializer: CreateContestProblemSerializer + response_serializer: ContestProblemSerializer + """ + serializer = CreateContestProblemSerializer(data=request.data) + if serializer.is_valid(): + data = serializer.data + contest_problem = ContestProblem.objects.create(title=data["title"], + description=data["description"], + input_description=data["input_description"], + output_description=data["output_description"], + test_case_id=data["test_case_id"], + samples=json.dumps(data["samples"]), + time_limit=data["time_limit"], + memory_limit=data["memory_limit"], + difficulty=data["difficulty"], + created_by=request.user, + hint=data["hint"], + contest=request.contest, + sort_index=data["sort_index"]) + return success_response(ContestProblemSerializer(contest_problem).data) + else: + serializer_invalid_response(serializer) + + def put(self, request): + """ + 比赛题目编辑json api接口 + --- + request_serializer: EditContestSerializer + response_serializer: ContestProblemSerializer + """ + serializer = EditContestSerializer(data=request.data) + if serializer.is_valid(): + data = serializer.data + try: + contest_problem = ContestProblem.objects.get(id=data["id"]) + except ContestProblem.DoesNotExist: + return error_response(u"该比赛题目不存在!") + contest_problem.title = data["title"] + contest_problem.description = data["description"] + contest_problem.input_description = data["input_description"] + contest_problem.output_description = data["output_description"] + contest_problem.test_case_id = data["test_case_id"] + contest_problem.time_limit = data["time_limit"] + contest_problem.memory_limit = data["memory_limit"] + contest_problem.difficulty = data["difficulty"] + contest_problem.samples = json.dumps(data["samples"]) + contest_problem.hint = data["hint"] + contest_problem.visible = data["visible"] + contest_problem.sort_index = data["sort_index"] + contest_problem.save() + return success_response(ContestProblem(contest_problem).data) + else: + return serializer_invalid_response(serializer) + + def get(self, request): + """ + 比赛题目分页json api接口 + --- + response_serializer: ProblemSerializer + """ + contest_problem_id = request.GET.get("contest_problem_id", None) + if contest_problem_id: + try: + contest_problem = ContestProblemSerializer.objects.get(id=contest_problem_id) + return success_response(ContestProblemSerializer(contest_problem).data) + except contest_problem.DoesNotExist: + return error_response(u"比赛题目不存在") + contest_problem = ContestProblem.objects.all().order_by("sort_index") + visible = request.GET.get("visible", None) + if visible: + contest_problem = contest_problem.filter(visible=(visible == "true")) + keyword = request.GET.get("keyword", None) + if keyword: + contest_problem = contest_problem.filter(Q(title__contains=keyword) | + Q(description__contains=keyword)) + + return paginate(request, contest_problem, ContestProblemSerializer) \ No newline at end of file diff --git a/problem/models.py b/problem/models.py index d6ac77bb..dbc886b6 100644 --- a/problem/models.py +++ b/problem/models.py @@ -32,8 +32,6 @@ class AbstractProblem(models.Model): # last_update_time = models.DateTimeField(auto_now=True) # 这个题是谁创建的 created_by = models.ForeignKey(User) - # 来源 - source = models.CharField(max_length=30, blank=True, null=True) # 时间限制 单位是毫秒 time_limit = models.IntegerField() # 内存限制 单位是MB @@ -54,3 +52,5 @@ class Problem(AbstractProblem): difficulty = models.IntegerField() # 标签 tags = models.ManyToManyField(ProblemTag) + # 来源 + source = models.CharField(max_length=30, blank=True, null=True) diff --git a/problem/tests.py b/problem/tests.py index 91affaea..925ffe08 100644 --- a/problem/tests.py +++ b/problem/tests.py @@ -164,3 +164,8 @@ class ProblemTagAdminAPITest(APITestCase): def test_get_all_problem_tag_successfully(self): self.assertEqual(self.client.get(self.url).data["code"], 0) + +class ProblemListPageTest(TestCase): + def setUp(self): + pass +