移除user time_zone, 统一使用submission_number和accepted_number字段
This commit is contained in:
19
account/migrations/0004_remove_userprofile_time_zone.py
Normal file
19
account/migrations/0004_remove_userprofile_time_zone.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.6 on 2017-08-23 09:04
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0003_userprofile_total_score'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='userprofile',
|
||||||
|
name='time_zone',
|
||||||
|
),
|
||||||
|
]
|
||||||
30
contest/migrations/0005_auto_20170823_0918.py
Normal file
30
contest/migrations/0005_auto_20170823_0918.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.6 on 2017-08-23 09:18
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0004_auto_20170717_1324'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='acmcontestrank',
|
||||||
|
old_name='total_ac_number',
|
||||||
|
new_name='accepted_number',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='acmcontestrank',
|
||||||
|
old_name='total_submission_number',
|
||||||
|
new_name='submission_number',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='oicontestrank',
|
||||||
|
old_name='total_submission_number',
|
||||||
|
new_name='submission_number',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -64,14 +64,14 @@ class Contest(models.Model):
|
|||||||
class ContestRank(models.Model):
|
class ContestRank(models.Model):
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
contest = models.ForeignKey(Contest)
|
contest = models.ForeignKey(Contest)
|
||||||
total_submission_number = models.IntegerField(default=0)
|
submission_number = models.IntegerField(default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
class ACMContestRank(ContestRank):
|
class ACMContestRank(ContestRank):
|
||||||
total_ac_number = models.IntegerField(default=0)
|
accepted_number = models.IntegerField(default=0)
|
||||||
# total_time is only for ACM contest total_time = ac time + none-ac times * 20 * 60
|
# total_time is only for ACM contest total_time = ac time + none-ac times * 20 * 60
|
||||||
total_time = models.IntegerField(default=0)
|
total_time = models.IntegerField(default=0)
|
||||||
# {23: {"is_ac": True, "ac_time": 8999, "error_number": 2, "is_first_ac": True}}
|
# {23: {"is_ac": True, "ac_time": 8999, "error_number": 2, "is_first_ac": True}}
|
||||||
@@ -92,7 +92,7 @@ class OIContestRank(ContestRank):
|
|||||||
db_table = "oi_contest_rank"
|
db_table = "oi_contest_rank"
|
||||||
|
|
||||||
def update_rank(self, submission):
|
def update_rank(self, submission):
|
||||||
self.total_submission_number += 1
|
self.submission_number += 1
|
||||||
|
|
||||||
|
|
||||||
class ContestAnnouncement(models.Model):
|
class ContestAnnouncement(models.Model):
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import pickle
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.core.cache import cache
|
|
||||||
from utils.api import APIView, validate_serializer
|
from utils.api import APIView, validate_serializer
|
||||||
|
from utils.cache import default_cache
|
||||||
|
from utils.constants import CacheKey
|
||||||
from account.decorators import login_required, check_contest_permission
|
from account.decorators import login_required, check_contest_permission
|
||||||
|
|
||||||
from ..models import ContestAnnouncement, Contest, ContestStatus, ContestRuleType
|
from ..models import ContestAnnouncement, Contest, ContestStatus, ContestRuleType
|
||||||
@@ -90,20 +92,25 @@ class ContestAccessAPI(APIView):
|
|||||||
class ContestRankAPI(APIView):
|
class ContestRankAPI(APIView):
|
||||||
def get_rank(self):
|
def get_rank(self):
|
||||||
if self.contest.rule_type == ContestRuleType.ACM:
|
if self.contest.rule_type == ContestRuleType.ACM:
|
||||||
rank = ACMContestRank.objects.filter(contest=self.contest). \
|
return ACMContestRank.objects.filter(contest=self.contest). \
|
||||||
select_related("user").order_by("-total_ac_number", "total_time")
|
select_related("user").order_by("-accepted_number", "total_time")
|
||||||
print(rank)
|
|
||||||
return ACMContestRankSerializer(rank, many=True).data
|
|
||||||
else:
|
else:
|
||||||
rank = OIContestRank.objects.filter(contest=self.contest). \
|
return OIContestRank.objects.filter(contest=self.contest). \
|
||||||
select_related("user").order_by("-total_score")
|
select_related("user").order_by("-total_score")
|
||||||
return OIContestRankSerializer(rank, many=True).data
|
|
||||||
|
|
||||||
@check_contest_permission
|
@check_contest_permission
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
cache_key = str(self.contest.id) + "_rank_cache"
|
if self.contest.rule_type == ContestRuleType.ACM:
|
||||||
rank = cache.get(cache_key)
|
model, serializer = ACMContestRank, ACMContestRankSerializer
|
||||||
if not rank:
|
else:
|
||||||
rank = self.get_rank()
|
model, serializer = OIContestRank, OIContestRankSerializer
|
||||||
cache.set(cache_key, rank)
|
|
||||||
return self.success(rank)
|
cache_key = CacheKey.contest_rank_cache + str(self.contest.id)
|
||||||
|
qs = default_cache.get(cache_key)
|
||||||
|
if not qs:
|
||||||
|
ranks = self.get_rank()
|
||||||
|
default_cache.set(cache_key, pickle.dumps(ranks))
|
||||||
|
else:
|
||||||
|
ranks = pickle.loads(qs)
|
||||||
|
|
||||||
|
return self.success(self.paginate_data(request, ranks, serializer))
|
||||||
|
|||||||
@@ -210,29 +210,29 @@ class JudgeDispatcher(object):
|
|||||||
if info["is_ac"]:
|
if info["is_ac"]:
|
||||||
return
|
return
|
||||||
|
|
||||||
rank.total_submission_number += 1
|
rank.submission_number += 1
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||||
rank.total_ac_number += 1
|
rank.accepted_number += 1
|
||||||
info["is_ac"] = True
|
info["is_ac"] = True
|
||||||
info["ac_time"] = (self.submission.create_time - self.contest.start_time).total_seconds()
|
info["ac_time"] = (self.submission.create_time - self.contest.start_time).total_seconds()
|
||||||
rank.total_time += info["ac_time"] + info["error_number"] * 20 * 60
|
rank.total_time += info["ac_time"] + info["error_number"] * 20 * 60
|
||||||
|
|
||||||
if problem.total_accepted_number == 1:
|
if problem.accepted_number == 1:
|
||||||
info["is_first_ac"] = True
|
info["is_first_ac"] = True
|
||||||
else:
|
else:
|
||||||
info["error_number"] += 1
|
info["error_number"] += 1
|
||||||
|
|
||||||
# 第一次提交
|
# 第一次提交
|
||||||
else:
|
else:
|
||||||
rank.total_submission_number += 1
|
rank.submission_number += 1
|
||||||
info = {"is_ac": False, "ac_time": 0, "error_number": 0, "is_first_ac": False}
|
info = {"is_ac": False, "ac_time": 0, "error_number": 0, "is_first_ac": False}
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||||
rank.total_ac_number += 1
|
rank.accepted_number += 1
|
||||||
info["is_ac"] = True
|
info["is_ac"] = True
|
||||||
info["ac_time"] = (self.submission.create_time - self.contest.start_time).total_seconds()
|
info["ac_time"] = (self.submission.create_time - self.contest.start_time).total_seconds()
|
||||||
rank.total_time += info["ac_time"]
|
rank.total_time += info["ac_time"]
|
||||||
|
|
||||||
if problem.total_accepted_number == 1:
|
if problem.accepted_number == 1:
|
||||||
info["is_first_ac"] = True
|
info["is_first_ac"] = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
35
problem/migrations/0006_auto_20170823_0918.py
Normal file
35
problem/migrations/0006_auto_20170823_0918.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.6 on 2017-08-23 09:18
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('problem', '0005_auto_20170815_1258'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
old_name='total_accepted_number',
|
||||||
|
new_name='accepted_number',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
old_name='total_submit_number',
|
||||||
|
new_name='submission_number',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='problem',
|
||||||
|
old_name='total_accepted_number',
|
||||||
|
new_name='accepted_number',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='problem',
|
||||||
|
old_name='total_submit_number',
|
||||||
|
new_name='submission_number',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -55,8 +55,8 @@ class AbstractProblem(models.Model):
|
|||||||
difficulty = models.CharField(max_length=32)
|
difficulty = models.CharField(max_length=32)
|
||||||
tags = models.ManyToManyField(ProblemTag)
|
tags = models.ManyToManyField(ProblemTag)
|
||||||
source = models.CharField(max_length=200, blank=True, null=True)
|
source = models.CharField(max_length=200, blank=True, null=True)
|
||||||
total_submit_number = models.BigIntegerField(default=0)
|
submission_number = models.BigIntegerField(default=0)
|
||||||
total_accepted_number = models.BigIntegerField(default=0)
|
accepted_number = models.BigIntegerField(default=0)
|
||||||
# {0: 0, 1: 0, 2: 0, 3: 0 ...}
|
# {0: 0, 1: 0, 2: 0, 3: 0 ...}
|
||||||
# the first number means JudgeStatus, the second number present count
|
# the first number means JudgeStatus, the second number present count
|
||||||
statistic_info = JSONField(default={})
|
statistic_info = JSONField(default={})
|
||||||
@@ -66,12 +66,12 @@ class AbstractProblem(models.Model):
|
|||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
def add_submission_number(self):
|
def add_submission_number(self):
|
||||||
self.total_submit_number = models.F("total_submit_number") + 1
|
self.submission_number = models.F("submission_number") + 1
|
||||||
self.save(update_fields=["total_submit_number"])
|
self.save(update_fields=["submission_number"])
|
||||||
|
|
||||||
def add_ac_number(self):
|
def add_ac_number(self):
|
||||||
self.total_accepted_number = models.F("total_accepted_number") + 1
|
self.accepted_number = models.F("accepted_number") + 1
|
||||||
self.save(update_fields=["total_accepted_number"])
|
self.save(update_fields=["accepted_number"])
|
||||||
|
|
||||||
|
|
||||||
class Problem(AbstractProblem):
|
class Problem(AbstractProblem):
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
class CacheKey:
|
class CacheKey:
|
||||||
waiting_queue = "waiting_queue"
|
waiting_queue = "waiting_queue"
|
||||||
|
contest_rank_cache = "contest_rank_cache_"
|
||||||
|
|||||||
Reference in New Issue
Block a user