完成ACM ContestProblem相关判题逻辑
contest,submission等表默认-create_time排序
This commit is contained in:
@@ -14,6 +14,10 @@ class Migration(migrations.Migration):
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='contest',
|
||||
options={'ordering': ('create_time',)},
|
||||
options={'ordering': ('-create_time',)},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='contestannouncement',
|
||||
options={'ordering': ('-create_time',)},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -58,7 +58,7 @@ class Contest(models.Model):
|
||||
|
||||
class Meta:
|
||||
db_table = "contest"
|
||||
ordering = ("create_time",)
|
||||
ordering = ("-create_time",)
|
||||
|
||||
|
||||
class ContestRank(models.Model):
|
||||
@@ -91,6 +91,9 @@ class OIContestRank(ContestRank):
|
||||
class Meta:
|
||||
db_table = "oi_contest_rank"
|
||||
|
||||
def update_rank(self, submission):
|
||||
self.total_submission_number += 1
|
||||
|
||||
|
||||
class ContestAnnouncement(models.Model):
|
||||
contest = models.ForeignKey(Contest)
|
||||
@@ -101,3 +104,4 @@ class ContestAnnouncement(models.Model):
|
||||
|
||||
class Meta:
|
||||
db_table = "contest_announcement"
|
||||
ordering = ("-create_time",)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from utils.api import DateTimeTZField, UsernameSerializer, serializers
|
||||
|
||||
from .models import Contest, ContestAnnouncement, ContestRuleType
|
||||
from .models import ACMContestRank, OIContestRank
|
||||
|
||||
|
||||
class CreateConetestSeriaizer(serializers.Serializer):
|
||||
@@ -61,3 +62,19 @@ class CreateContestAnnouncementSerializer(serializers.Serializer):
|
||||
class ContestPasswordVerifySerializer(serializers.Serializer):
|
||||
contest_id = serializers.IntegerField()
|
||||
password = serializers.CharField(max_length=30, required=True)
|
||||
|
||||
|
||||
class ACMContestRankSerializer(serializers.ModelSerializer):
|
||||
user = UsernameSerializer()
|
||||
submission_info = serializers.JSONField()
|
||||
|
||||
class Meta:
|
||||
model = ACMContestRank
|
||||
|
||||
|
||||
class OIContestRankSerializer(serializers.ModelSerializer):
|
||||
user = UsernameSerializer()
|
||||
submission_info = serializers.JSONField()
|
||||
|
||||
class Meta:
|
||||
model = OIContestRank
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
from django.utils.timezone import now
|
||||
from django.db.models import Q
|
||||
from django.core.cache import cache
|
||||
from utils.api import APIView, validate_serializer
|
||||
from account.decorators import login_required
|
||||
from account.decorators import login_required, check_contest_permission
|
||||
|
||||
from ..models import ContestAnnouncement, Contest, ContestStatus
|
||||
from ..models import ContestAnnouncement, Contest, ContestStatus, ContestRuleType
|
||||
from ..models import OIContestRank, ACMContestRank
|
||||
from ..serializers import ContestAnnouncementSerializer
|
||||
from ..serializers import ContestSerializer, ContestPasswordVerifySerializer
|
||||
from ..serializers import OIContestRankSerializer, ACMContestRankSerializer
|
||||
|
||||
|
||||
class ContestAnnouncementListAPI(APIView):
|
||||
@@ -11,7 +16,7 @@ class ContestAnnouncementListAPI(APIView):
|
||||
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")
|
||||
data = ContestAnnouncement.objects.filter(contest_id=contest_id)
|
||||
max_id = request.GET.get("max_id")
|
||||
if max_id:
|
||||
data = data.filter(id__gt=max_id)
|
||||
@@ -30,8 +35,20 @@ class ContestAPI(APIView):
|
||||
|
||||
contests = Contest.objects.filter(visible=True)
|
||||
keyword = request.GET.get("keyword")
|
||||
rule_type = request.GET.get("rule_type")
|
||||
status = request.GET.get("status")
|
||||
if keyword:
|
||||
contests = contests.filter(title__contains=keyword)
|
||||
if rule_type:
|
||||
contests = contests.filter(rule_type=rule_type)
|
||||
if status:
|
||||
cur = now()
|
||||
if status == ContestStatus.CONTEST_NOT_START:
|
||||
contests = contests.filter(start_time__gt=cur)
|
||||
elif status == ContestStatus.CONTEST_ENDED:
|
||||
contests = contests.filter(end_time__lt=cur)
|
||||
else:
|
||||
contests = contests.filter(Q(start_time__lte=cur) & Q(end_time__gte=cur))
|
||||
return self.success(self.paginate_data(request, contests, ContestSerializer))
|
||||
|
||||
|
||||
@@ -68,3 +85,24 @@ class ContestAccessAPI(APIView):
|
||||
return self.success({"Access": True})
|
||||
else:
|
||||
return self.success({"Access": False})
|
||||
|
||||
|
||||
class ContestRankAPI(APIView):
|
||||
def get_rank(self):
|
||||
if self.contest.contest_type == ContestRuleType.ACM:
|
||||
rank = ACMContestRank.objects.filter(contest=self.contest). \
|
||||
select_related("user").order_by("-total_ac_number", "total_time")
|
||||
return ACMContestRankSerializer(rank, many=True).data
|
||||
else:
|
||||
rank = OIContestRank.objects.filter(contest=self.contest). \
|
||||
select_related("user").order_by("-total_score")
|
||||
return OIContestRankSerializer(rank, many=True).data
|
||||
|
||||
@check_contest_permission
|
||||
def get(self, request):
|
||||
cache_key = str(self.contest.id) + "_rank_cache"
|
||||
rank = cache.get(cache_key)
|
||||
if not rank:
|
||||
rank = self.get_rank()
|
||||
cache.set(cache_key, rank)
|
||||
return self.success(rank)
|
||||
|
||||
Reference in New Issue
Block a user