添加比赛排名的封榜功能,rank页面从redis中读取排名信息而不是向mysql查询,封榜后redis中的数据便不再更新了

This commit is contained in:
sxw@401 2015-09-12 22:00:24 +08:00
parent a084614af9
commit 444cbc4324
4 changed files with 42 additions and 18 deletions

View File

@ -13,7 +13,7 @@ class CreateContestSerializer(serializers.Serializer):
description = serializers.CharField(max_length=5000)
mode = serializers.IntegerField()
contest_type = serializers.IntegerField()
show_rank = serializers.BooleanField()
real_time_rank = serializers.BooleanField()
show_user_submission = serializers.BooleanField()
password = serializers.CharField(max_length=30, required=False, default=None)
start_time = serializers.DateTimeField()
@ -47,7 +47,7 @@ class EditContestSerializer(serializers.Serializer):
description = serializers.CharField(max_length=10000)
mode = serializers.IntegerField()
contest_type = serializers.IntegerField()
show_rank = serializers.BooleanField()
real_time_rank = serializers.BooleanField()
show_user_submission = serializers.BooleanField()
password = serializers.CharField(max_length=30, required=False, default=None)
start_time = serializers.DateTimeField()

View File

@ -24,6 +24,8 @@ from .serializers import (CreateContestSerializer, ContestSerializer, EditContes
CreateContestProblemSerializer, ContestProblemSerializer,
EditContestProblemSerializer, ContestPasswordVerifySerializer,
EditContestProblemSerializer)
from oj.settings import REDIS_CACHE
import redis
class ContestAdminAPIView(APIView):
@ -61,7 +63,7 @@ class ContestAdminAPIView(APIView):
try:
contest = Contest.objects.create(title=data["title"], description=data["description"],
mode=data["mode"], contest_type=data["contest_type"],
show_rank=data["show_rank"], password=data["password"],
real_time_rank=data["real_time_rank"], password=data["password"],
show_user_submission=data["show_user_submission"],
start_time=dateparse.parse_datetime(data["start_time"]),
end_time=dateparse.parse_datetime(data["end_time"]),
@ -115,7 +117,7 @@ class ContestAdminAPIView(APIView):
contest.description = data["description"]
contest.mode = data["mode"]
contest.contest_type = data["contest_type"]
contest.show_rank = data["show_rank"]
contest.real_time_rank = data["real_time_rank"]
contest.show_user_submission = data["show_user_submission"]
contest.start_time = dateparse.parse_datetime(data["start_time"])
contest.end_time = dateparse.parse_datetime(data["end_time"])
@ -397,19 +399,33 @@ def _cmp(x, y):
def contest_rank_page(request, contest_id):
contest = Contest.objects.get(id=contest_id)
contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")
result = ContestSubmission.objects.filter(contest=contest).values("user_id").\
annotate(total_submit=Sum("total_submission_number"))
for i in range(0, len(result)):
# 这个人所有的提交
submissions = ContestSubmission.objects.filter(user_id=result[i]["user_id"], contest_id=contest_id)
result[i]["submissions"] = {}
for item in submissions:
result[i]["submissions"][item.problem_id] = item
result[i]["total_ac"] = submissions.filter(ac=True).count()
result[i]["user"] = User.objects.get(id=result[i]["user_id"])
result[i]["total_time"] = submissions.filter(ac=True).aggregate(total_time=Sum("total_time"))["total_time"]
r = redis.Redis(host=REDIS_CACHE["host"], port=REDIS_CACHE["port"], db=REDIS_CACHE["db"])
if contest.real_time_rank:
# 更新rank
result = ContestSubmission.objects.filter(contest=contest).values("user_id"). \
annotate(total_submit=Sum("total_submission_number"))
for i in range(0, len(result)):
# 这个人所有的提交
submissions = ContestSubmission.objects.filter(user_id=result[i]["user_id"], contest_id=contest_id)
result[i]["submissions"] = {}
for item in submissions:
result[i]["submissions"][item.problem_id] = item
result[i]["total_ac"] = submissions.filter(ac=True).count()
result[i]["user"] = User.objects.get(id=result[i]["user_id"])
result[i]["total_time"] = submissions.filter(ac=True).aggregate(total_time=Sum("total_time"))["total_time"]
result = sorted(result, cmp=_cmp, reverse=True)
r.set("contest_rank_" + contest_id, json.dumps(list(result)))
else:
# 从缓存读取排名信息
result = r.get("contest_rank_" + contest_id)
if result:
result = json.loads(result)
else:
result = []
return render(request, "oj/contest/contest_rank.html",
{"contest": contest, "contest_problems": contest_problems,
"result": sorted(result, cmp=_cmp, reverse=True),
"auto_refresh": request.GET.get("auto_refresh", None) == "true"})
"result": result,
"auto_refresh": request.GET.get("auto_refresh", None) == "true",
"real_time_rank": contest.real_time_rank})

View File

@ -20,6 +20,13 @@
</div>
<div class="row">
<div class="col-lg-12">
<h2 class="text-center">排名(
{% if real_time_rank %}
实时
{% else %}
已封榜
{% endif %})
</h2>
{% if result %}
<table class="table table-bordered">
<thead>

View File

@ -67,7 +67,8 @@
<tbody>
{% for item in submissions %}
<tr>
{% ifequal item.user_id request.user.id %}
{% if item.user_id == request.user.id and request.user.admin_type == 2%}
<th scope="row"><a href="/submission/{{ item.id }}/">
{{ forloop.counter |add:start_id }}</a></th>
{% else %}