From 02940029ef7cf4ba35299bbfe87ce9849d04bfa0 Mon Sep 17 00:00:00 2001 From: virusdefender Date: Sun, 29 Jan 2017 17:04:56 +0800 Subject: [PATCH] add contest announcement --- .../0002_contestannouncement_created_by.py | 24 ++++++++++++++ contest/models.py | 1 + contest/serializers.py | 18 +++++++++-- contest/urls/admin.py | 5 +-- contest/urls/oj.py | 7 ++++ contest/views/admin.py | 32 +++++++++++++++++-- contest/views/oj.py | 16 ++++++++++ oj/urls.py | 1 + 8 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 contest/migrations/0002_contestannouncement_created_by.py create mode 100644 contest/urls/oj.py create mode 100644 contest/views/oj.py diff --git a/contest/migrations/0002_contestannouncement_created_by.py b/contest/migrations/0002_contestannouncement_created_by.py new file mode 100644 index 00000000..be523092 --- /dev/null +++ b/contest/migrations/0002_contestannouncement_created_by.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.12 on 2017-01-29 08:56 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('contest', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='contestannouncement', + name='created_by', + field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + preserve_default=False, + ), + ] diff --git a/contest/models.py b/contest/models.py index 55ad24d5..13da3a8f 100644 --- a/contest/models.py +++ b/contest/models.py @@ -107,6 +107,7 @@ class ContestAnnouncement(models.Model): contest = models.ForeignKey(Contest) title = models.CharField(max_length=128) content = RichTextField() + created_by = models.ForeignKey(User) create_time = models.DateTimeField(auto_now_add=True) class Meta: diff --git a/contest/serializers.py b/contest/serializers.py index 9795f1c9..c99c16dc 100644 --- a/contest/serializers.py +++ b/contest/serializers.py @@ -1,6 +1,6 @@ from utils.api import DateTimeTZField, UsernameSerializer, serializers -from .models import Contest, ContestRuleType +from .models import Contest, ContestAnnouncement, ContestRuleType class CreateConetestSeriaizer(serializers.Serializer): @@ -33,6 +33,20 @@ class EditConetestSeriaizer(serializers.Serializer): description = serializers.CharField() start_time = serializers.DateTimeField() end_time = serializers.DateTimeField() - password = serializers.CharField(allow_blank=True, max_length=32) + password = serializers.CharField(allow_blank=True, allow_null=True, max_length=32) visible = serializers.BooleanField() real_time_rank = serializers.BooleanField() + + +class ContestAnnouncementSerializer(serializers.ModelSerializer): + created_by = UsernameSerializer() + create_time = DateTimeTZField() + + class Meta: + model = ContestAnnouncement + + +class CreateContestAnnouncementSerializer(serializers.Serializer): + title = serializers.CharField(max_length=128) + content = serializers.CharField() + contest_id = serializers.IntegerField() diff --git a/contest/urls/admin.py b/contest/urls/admin.py index 75eb8f06..d9ea9c9d 100644 --- a/contest/urls/admin.py +++ b/contest/urls/admin.py @@ -1,7 +1,8 @@ from django.conf.urls import url -from ..views.admin import ContestAPI +from ..views.admin import ContestAnnouncementAPI, ContestAPI urlpatterns = [ - url(r"^contest", ContestAPI.as_view(), name="contest_api"), + url(r"^contest$", ContestAPI.as_view(), name="contest_api"), + url(r"^contest/announcement$", ContestAnnouncementAPI.as_view(), name="contest_announcement_admin_api") ] diff --git a/contest/urls/oj.py b/contest/urls/oj.py new file mode 100644 index 00000000..a9290a26 --- /dev/null +++ b/contest/urls/oj.py @@ -0,0 +1,7 @@ +from django.conf.urls import url + +from ..views.oj import ContestAnnouncementListAPI + +urlpatterns = [ + url(r"^contest", ContestAnnouncementListAPI.as_view(), name="contest_list_api"), +] diff --git a/contest/views/admin.py b/contest/views/admin.py index 7a64240e..096cb90f 100644 --- a/contest/views/admin.py +++ b/contest/views/admin.py @@ -2,8 +2,11 @@ import dateutil.parser from utils.api import APIView, validate_serializer -from ..models import Contest -from ..serializers import ContestSerializer, CreateConetestSeriaizer, EditConetestSeriaizer +from ..models import Contest, ContestAnnouncement +from ..serializers import (ContestAnnouncementSerializer, ContestSerializer, + CreateConetestSeriaizer, + CreateContestAnnouncementSerializer, + EditConetestSeriaizer) class ContestAPI(APIView): @@ -60,3 +63,28 @@ class ContestAPI(APIView): if request.user.is_admin_role(): contests = contests.filter(created_by=request.user) return self.success(self.paginate_data(request, contests, ContestSerializer)) + + +class ContestAnnouncementAPI(APIView): + @validate_serializer(CreateContestAnnouncementSerializer) + def post(self, request): + data = request.data + try: + contest = Contest.objects.get(id=data.pop("contest_id")) + if request.user.is_admin_role(): + contest = contest.get(created_by=request.user) + data["contest"] = contest + data["created_by"] = request.user + except Contest.DoesNotExist: + return self.error("Contest does not exist") + announcement = ContestAnnouncement.objects.create(**data) + return self.success(ContestAnnouncementSerializer(announcement).data) + + def delete(self, request): + announcement_id = request.GET.get("id") + if announcement_id: + if request.user.is_admin_role(): + ContestAnnouncement.objects.filter(id=announcement_id, contest__created_by=request.user).delete() + else: + ContestAnnouncement.objects.filter(id=announcement_id).delete() + return self.success() diff --git a/contest/views/oj.py b/contest/views/oj.py new file mode 100644 index 00000000..e9ffe811 --- /dev/null +++ b/contest/views/oj.py @@ -0,0 +1,16 @@ +from utils.api import APIView + +from ..models import ContestAnnouncement +from ..serializers import ContestAnnouncementSerializer + + +class ContestAnnouncementListAPI(APIView): + def get(self, request): + contest_id = request.GET.get("contest_id") + if not contest_id: + return self.error("Invalid parameter") + data = ContestAnnouncement.objects.filter(contest_id=contest_id).order_by("-create_time") + max_id = request.GET.get("max_id") + if max_id: + data = data.filter(id__gt=max_id) + return self.success(ContestAnnouncementSerializer(data, many=True).data) diff --git a/oj/urls.py b/oj/urls.py index bdcc1467..b8cc62d1 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -9,4 +9,5 @@ urlpatterns = [ url(r"^api/", include("problem.urls.oj")), url(r"^api/admin/", include("problem.urls.admin")), url(r"^api/admin/", include("contest.urls.admin")), + url(r"^api/", include("contest.urls.oj")) ]