2015-08-18 06:59:00 +00:00
|
|
|
|
# coding=utf-8
|
|
|
|
|
import json
|
2015-08-22 08:08:39 +00:00
|
|
|
|
import datetime
|
2015-08-22 12:42:21 +00:00
|
|
|
|
from django.utils.timezone import localtime
|
2015-06-26 07:59:53 +00:00
|
|
|
|
from django.shortcuts import render
|
2015-08-18 06:59:00 +00:00
|
|
|
|
from django.db import IntegrityError
|
2015-08-21 10:16:34 +00:00
|
|
|
|
from django.utils import dateparse
|
2015-08-18 06:59:00 +00:00
|
|
|
|
from django.db.models import Q
|
2015-08-22 08:08:39 +00:00
|
|
|
|
from django.core.paginator import Paginator
|
2015-08-18 06:59:00 +00:00
|
|
|
|
from rest_framework.views import APIView
|
2015-08-18 12:12:27 +00:00
|
|
|
|
from utils.shortcuts import (serializer_invalid_response, error_response,
|
|
|
|
|
success_response, paginate, rand_str, error_page)
|
|
|
|
|
|
|
|
|
|
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
|
2015-08-22 12:46:52 +00:00
|
|
|
|
from account.decorators import login_required
|
2015-08-18 12:12:27 +00:00
|
|
|
|
from group.models import Group
|
2015-08-22 08:08:39 +00:00
|
|
|
|
from announcement.models import Announcement
|
2015-06-26 07:59:53 +00:00
|
|
|
|
|
2015-08-18 06:59:00 +00:00
|
|
|
|
from .models import Contest, ContestProblem
|
|
|
|
|
from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer,
|
2015-08-22 12:46:52 +00:00
|
|
|
|
CreateContestProblemSerializer, ContestProblemSerializer,
|
Merge branch 'dev' into virusdefender-dev
* dev:
增加了比赛列表页
[后端]去掉了用于生产序号的javascript,改为使用模板过滤器实现(我的所有提交)
[前端]修改完善了添加比赛页面, 比赛列表功能仍不全面,稍后改进[CI SKIP]
修改了css引用方式[CI SKIP]
[后端]修改了contest中 api-docs 的小bug[CI SKIP]
创建前台比赛列表
去掉冗余语句,因为page变量已经有默认值了,不能为空
[后端]前台我的提交页面 增强提交序号的显示,原来是显示真实id即随机的散列值,不好看,现在改成自然数序列,但需要结合javascript生成,且是相对值,因为数据库里没有这个字段,有点别扭了. 第二,添加了用户没有提交记录的反馈. 第三,本打算增加筛选功能,但因为URL难以统一作罢,只有在增加新的url才能较好的处理,下次再说拜
[前端]比赛列表页面(后台)的进一步完善,不包含api
[后端]修改了我的提交列表的模板样式,整理格式
[后端]修改我的提交页面,去掉了冗余语句,并添加测试
[后端-前台]添加了submissions分页显示(只显示当前用户的提交),调用已有的view完成单个submission的显示.显示界面与问题分页显示统一.问题是id的显示.url:http://127.0.0.1:8000/my_submissions/
[前端]修改添加比赛页面,新增了使用小组api查询该用户所创建的所有的小组的功能[CI SKIP]
[ÂâçÁ´Ø]Ê∑ªÂä†ÊØî˵õÈ°µÈù¢Ëøõ‰∏ÄÊ≠•ÂÆåÂñÑ,Ê∑ªÂä†Â≠óÊƵÂåÖÊã¨ÊòØÂê¶ÊòæÁ§∫Êèê‰∫§,ÊØî˵õÊ®°Âºè,ÈóÆÈ¢òÂàÜÂĺ,ÂÖÅËÆ∏ÂèÇÂä†ÊØî˵õÁöÑÁî®Êà∑ÁªÑ,Âπ∂ÂÆåÂñÑÂÜÖÈÉ®ÈĪËæë,Âü∫Êú¨ÂèØÁ∫Ü,Âè™ÊòØÊ≤°ÂÜôajaxÊèê‰∫§Êï∞ÊçÆ,ÂíåÂïÊãâÂÂèñÂ∞èÁªÑ‰ø°ÊÅØÁöÑÈÉ®ÂàÜ[CI SKIP]
[前端]修改了添加比赛页的形式结构,仍有bug[CI SKIP]
Ê∑[ÂâçÁ´Ø]Ê∑ªÂä†ÊØîËÂêéÂè∞ÊØî˵õÂàóË°®[CI SKIP]
[ÂâçÁ´Ø]Áªü‰∏ÄÈóÆÈ¢òÈá,ÊØî˵õÂàóË°®jsÁöÑÊñቪ∂Âêç_list.js. Ê∑ªÂ䆉∫ÜÊØî˵õÂàóË°®ÂíåÁºñËæëÊØî˵õÁöÑÈ°µÈù¢(§߉Ωì§ʆ∑ºè)[CI SKIP]
Conflicts:
contest/views.py
2015-08-22 12:49:42 +00:00
|
|
|
|
EditContestProblemSerializer, ContestPasswordVerifySerializer,
|
|
|
|
|
EditContestProblemSerializer)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2015-08-18 12:12:27 +00:00
|
|
|
|
groups = []
|
|
|
|
|
# 首先判断比赛的类型: 0 即为是小组赛,1 即为是无密码的公开赛,2 即为是有密码的公开赛
|
|
|
|
|
# 此时为有密码的公开赛,并且此时只能超级管理员才有权限此创建比赛
|
2015-08-19 09:53:43 +00:00
|
|
|
|
if data["contest_type"] in [1, 2]:
|
|
|
|
|
if request.user.admin_type != SUPER_ADMIN:
|
|
|
|
|
return error_response(u"只有超级管理员才可创建公开赛")
|
2015-08-18 12:12:27 +00:00
|
|
|
|
if data["contest_type"] == 2:
|
|
|
|
|
if not data["password"]:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
return error_response(u"此比赛为有密码的公开赛,密码不可为空")
|
|
|
|
|
|
|
|
|
|
# 没有密码的公开赛 没有密码的小组赛
|
|
|
|
|
elif data["contest_type"] == 0:
|
|
|
|
|
if request.user.admin_type == SUPER_ADMIN:
|
|
|
|
|
groups = Group.objects.filter(id__in=data["groups"])
|
2015-08-18 12:12:27 +00:00
|
|
|
|
else:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
|
|
|
|
|
if not groups.count():
|
|
|
|
|
return error_response(u"请至少选择一个小组")
|
2015-08-21 10:16:34 +00:00
|
|
|
|
if data["start_time"] >= data["end_time"]:
|
|
|
|
|
return error_response(u"比赛的开始时间不能晚于或等于比赛结束的时间")
|
2015-08-18 06:59:00 +00:00
|
|
|
|
try:
|
|
|
|
|
contest = Contest.objects.create(title=data["title"], description=data["description"],
|
2015-08-21 10:16:34 +00:00
|
|
|
|
mode=data["mode"], contest_type=data["contest_type"],
|
|
|
|
|
show_rank=data["show_rank"], password=data["password"],
|
2015-08-18 12:12:27 +00:00
|
|
|
|
show_user_submission=data["show_user_submission"],
|
2015-08-21 10:16:34 +00:00
|
|
|
|
start_time=dateparse.parse_datetime(data["start_time"]),
|
|
|
|
|
end_time=dateparse.parse_datetime(data["end_time"]),
|
|
|
|
|
created_by=request.user, visible=data["visible"])
|
2015-08-18 06:59:00 +00:00
|
|
|
|
except IntegrityError:
|
|
|
|
|
return error_response(u"比赛名已经存在")
|
2015-08-18 12:12:27 +00:00
|
|
|
|
contest.groups.add(*groups)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
return success_response(ContestSerializer(contest).data)
|
|
|
|
|
else:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
|
|
|
|
|
def put(self, request):
|
|
|
|
|
"""
|
|
|
|
|
比赛编辑json api接口
|
|
|
|
|
---
|
|
|
|
|
request_serializer: EditContestSerializer
|
|
|
|
|
response_serializer: ContestSerializer
|
|
|
|
|
"""
|
|
|
|
|
serializer = EditContestSerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
2015-08-19 09:53:43 +00:00
|
|
|
|
groups = []
|
2015-08-18 06:59:00 +00:00
|
|
|
|
try:
|
|
|
|
|
contest = Contest.objects.get(id=data["id"])
|
|
|
|
|
except Contest.DoesNotExist:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
return error_response(u"该比赛不存在!")
|
2015-08-18 06:59:00 +00:00
|
|
|
|
try:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
contest = Contest.objects.get(title=data["title"])
|
|
|
|
|
if contest.id != data["id"]:
|
|
|
|
|
return error_response(u"该比赛名称已经存在")
|
|
|
|
|
except Contest.DoesNotExist:
|
|
|
|
|
pass
|
|
|
|
|
if data["contest_type"] in [1, 2]:
|
|
|
|
|
if request.user.admin_type != SUPER_ADMIN:
|
|
|
|
|
return error_response(u"只有超级管理员才可创建公开赛")
|
|
|
|
|
if data["contest_type"] == 2:
|
|
|
|
|
if not data["password"]:
|
|
|
|
|
return error_response(u"此比赛为有密码的公开赛,密码不可为空")
|
|
|
|
|
elif data["contest_type"] == 0:
|
|
|
|
|
if request.user.admin_type == SUPER_ADMIN:
|
|
|
|
|
groups = Group.objects.filter(id__in=data["groups"])
|
|
|
|
|
else:
|
|
|
|
|
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
|
|
|
|
|
if not groups.count():
|
|
|
|
|
return error_response(u"请至少选择一个小组")
|
2015-08-21 10:16:34 +00:00
|
|
|
|
if data["start_time"] >= data["end_time"]:
|
|
|
|
|
return error_response(u"比赛的开始时间不能晚于或等于比赛结束的时间")
|
2015-08-19 09:53:43 +00:00
|
|
|
|
contest.title = data["title"]
|
|
|
|
|
contest.description = data["description"]
|
|
|
|
|
contest.mode = data["mode"]
|
2015-08-21 10:16:34 +00:00
|
|
|
|
contest.contest_type = data["contest_type"]
|
2015-08-19 09:53:43 +00:00
|
|
|
|
contest.show_rank = data["show_rank"]
|
|
|
|
|
contest.show_user_submission = data["show_user_submission"]
|
2015-08-21 10:16:34 +00:00
|
|
|
|
contest.start_time = dateparse.parse_datetime(data["start_time"])
|
|
|
|
|
contest.end_time = dateparse.parse_datetime(data["end_time"])
|
|
|
|
|
contest.visible = data["visible"]
|
2015-08-19 09:53:43 +00:00
|
|
|
|
contest.password = data["password"]
|
|
|
|
|
contest.save()
|
2015-08-18 06:59:00 +00:00
|
|
|
|
|
2015-08-19 09:53:43 +00:00
|
|
|
|
contest.groups.clear()
|
|
|
|
|
contest.groups.add(*groups)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
return success_response(ContestSerializer(contest).data)
|
|
|
|
|
else:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
|
|
|
|
|
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
|
2015-08-22 06:00:09 +00:00
|
|
|
|
try:
|
|
|
|
|
contest = Contest.objects.get(id=data["contest_id"])
|
|
|
|
|
except Contest.DoesNotExist:
|
|
|
|
|
return error_response(u"比赛不存在")
|
2015-08-18 06:59:00 +00:00
|
|
|
|
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"],
|
|
|
|
|
created_by=request.user,
|
|
|
|
|
hint=data["hint"],
|
2015-08-22 06:00:09 +00:00
|
|
|
|
contest=contest,
|
2015-08-18 06:59:00 +00:00
|
|
|
|
sort_index=data["sort_index"])
|
|
|
|
|
return success_response(ContestProblemSerializer(contest_problem).data)
|
|
|
|
|
else:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
|
|
|
|
|
def put(self, request):
|
|
|
|
|
"""
|
|
|
|
|
比赛题目编辑json api接口
|
|
|
|
|
---
|
2015-08-22 06:00:09 +00:00
|
|
|
|
request_serializer: EditContestProblemSerializer
|
2015-08-18 06:59:00 +00:00
|
|
|
|
response_serializer: ContestProblemSerializer
|
|
|
|
|
"""
|
2015-08-22 06:00:09 +00:00
|
|
|
|
serializer = EditContestProblemSerializer(data=request.data)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
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.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()
|
2015-08-22 06:00:09 +00:00
|
|
|
|
return success_response(ContestProblemSerializer(contest_problem).data)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
|
|
|
|
def get(self, request):
|
|
|
|
|
"""
|
|
|
|
|
比赛题目分页json api接口
|
|
|
|
|
---
|
2015-08-22 12:42:21 +00:00
|
|
|
|
response_serializer: ContestProblemSerializer
|
2015-08-18 06:59:00 +00:00
|
|
|
|
"""
|
|
|
|
|
contest_problem_id = request.GET.get("contest_problem_id", None)
|
|
|
|
|
if contest_problem_id:
|
|
|
|
|
try:
|
2015-08-19 09:53:43 +00:00
|
|
|
|
contest_problem = ContestProblem.objects.get(id=contest_problem_id)
|
2015-08-18 06:59:00 +00:00
|
|
|
|
return success_response(ContestProblemSerializer(contest_problem).data)
|
2015-08-19 09:53:43 +00:00
|
|
|
|
except ContestProblem.DoesNotExist:
|
2015-08-18 06:59:00 +00:00
|
|
|
|
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))
|
|
|
|
|
|
2015-08-22 12:46:52 +00:00
|
|
|
|
return paginate(request, contest_problem, ContestProblemSerializer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ContestPasswordVerifyAPIView(APIView):
|
|
|
|
|
@login_required
|
|
|
|
|
def post(self, request):
|
|
|
|
|
serializer = ContestPasswordVerifySerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = request.data
|
|
|
|
|
try:
|
|
|
|
|
contest = Contest.objects.get(id=data["contest_id"], contest_type=2)
|
|
|
|
|
except Contest.DoesNotExist:
|
|
|
|
|
return error_response(u"密码错误")
|
|
|
|
|
|
|
|
|
|
if data["password"] != contest.password:
|
|
|
|
|
return error_response(u" 密码错误")
|
|
|
|
|
else:
|
|
|
|
|
print request.session.get("contests", None)
|
|
|
|
|
if "contests" not in request.session:
|
|
|
|
|
request.session["contests"] = []
|
|
|
|
|
request.session["contests"].append(int(data["contest_id"]))
|
|
|
|
|
print request.session["contests"]
|
|
|
|
|
|
|
|
|
|
return success_response(True)
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_user_contest_permission(request, contest):
|
|
|
|
|
# 有密码的公开赛
|
|
|
|
|
if contest.contest_type == 2:
|
|
|
|
|
# 没有输入过密码
|
|
|
|
|
if contest.id not in request.session.get("contests", []):
|
|
|
|
|
return {"result": False, "reason": "password_protect"}
|
|
|
|
|
|
|
|
|
|
# 指定小组参加的
|
|
|
|
|
if contest.contest_type == 0:
|
|
|
|
|
if not contest.groups.filter(id__in=request.user.group_set.all()).exists():
|
|
|
|
|
return {"result": False, "reason": "limited_group"}
|
|
|
|
|
return {"result": True}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def contest_page(request, contest_id):
|
|
|
|
|
print request.session.get("contests", None)
|
|
|
|
|
try:
|
|
|
|
|
contest = Contest.objects.get(id=contest_id)
|
|
|
|
|
except Contest.DoesNotExist:
|
|
|
|
|
return error_page(request, u"比赛不存在")
|
|
|
|
|
|
|
|
|
|
Contest.objects.filter(Q(contest_type__in=[1, 2]) | Q(groups__in=request.user.group_set.all()))
|
|
|
|
|
|
|
|
|
|
result = check_user_contest_permission(request, contest)
|
|
|
|
|
if not result["result"]:
|
|
|
|
|
return render(request, "oj/contest/contest_no_privilege.html", {"contenst": contest, "reason": result["reason"]})
|
|
|
|
|
|
Merge branch 'dev' into virusdefender-dev
* dev:
增加了比赛列表页
[后端]去掉了用于生产序号的javascript,改为使用模板过滤器实现(我的所有提交)
[前端]修改完善了添加比赛页面, 比赛列表功能仍不全面,稍后改进[CI SKIP]
修改了css引用方式[CI SKIP]
[后端]修改了contest中 api-docs 的小bug[CI SKIP]
创建前台比赛列表
去掉冗余语句,因为page变量已经有默认值了,不能为空
[后端]前台我的提交页面 增强提交序号的显示,原来是显示真实id即随机的散列值,不好看,现在改成自然数序列,但需要结合javascript生成,且是相对值,因为数据库里没有这个字段,有点别扭了. 第二,添加了用户没有提交记录的反馈. 第三,本打算增加筛选功能,但因为URL难以统一作罢,只有在增加新的url才能较好的处理,下次再说拜
[前端]比赛列表页面(后台)的进一步完善,不包含api
[后端]修改了我的提交列表的模板样式,整理格式
[后端]修改我的提交页面,去掉了冗余语句,并添加测试
[后端-前台]添加了submissions分页显示(只显示当前用户的提交),调用已有的view完成单个submission的显示.显示界面与问题分页显示统一.问题是id的显示.url:http://127.0.0.1:8000/my_submissions/
[前端]修改添加比赛页面,新增了使用小组api查询该用户所创建的所有的小组的功能[CI SKIP]
[ÂâçÁ´Ø]Ê∑ªÂä†ÊØî˵õÈ°µÈù¢Ëøõ‰∏ÄÊ≠•ÂÆåÂñÑ,Ê∑ªÂä†Â≠óÊƵÂåÖÊã¨ÊòØÂê¶ÊòæÁ§∫Êèê‰∫§,ÊØî˵õÊ®°Âºè,ÈóÆÈ¢òÂàÜÂĺ,ÂÖÅËÆ∏ÂèÇÂä†ÊØî˵õÁöÑÁî®Êà∑ÁªÑ,Âπ∂ÂÆåÂñÑÂÜÖÈÉ®ÈĪËæë,Âü∫Êú¨ÂèØÁ∫Ü,Âè™ÊòØÊ≤°ÂÜôajaxÊèê‰∫§Êï∞ÊçÆ,ÂíåÂïÊãâÂÂèñÂ∞èÁªÑ‰ø°ÊÅØÁöÑÈÉ®ÂàÜ[CI SKIP]
[前端]修改了添加比赛页的形式结构,仍有bug[CI SKIP]
Ê∑[ÂâçÁ´Ø]Ê∑ªÂä†ÊØîËÂêéÂè∞ÊØî˵õÂàóË°®[CI SKIP]
[ÂâçÁ´Ø]Áªü‰∏ÄÈóÆÈ¢òÈá,ÊØî˵õÂàóË°®jsÁöÑÊñቪ∂Âêç_list.js. Ê∑ªÂ䆉∫ÜÊØî˵õÂàóË°®ÂíåÁºñËæëÊØî˵õÁöÑÈ°µÈù¢(§߉Ωì§ʆ∑ºè)[CI SKIP]
Conflicts:
contest/views.py
2015-08-22 12:49:42 +00:00
|
|
|
|
return render(request, "oj/contest/contest_index.html", {"contest": contest})
|
|
|
|
|
|
|
|
|
|
|
2015-08-22 08:08:39 +00:00
|
|
|
|
def contest_list_page(request, page=1):
|
|
|
|
|
# 正常情况
|
|
|
|
|
contests = Contest.objects.filter(visible=True)
|
|
|
|
|
|
|
|
|
|
# 搜索的情况
|
|
|
|
|
keyword = request.GET.get("keyword", None)
|
|
|
|
|
if keyword:
|
|
|
|
|
contests = contests.filter(title__contains=keyword)
|
|
|
|
|
|
2015-08-22 12:42:21 +00:00
|
|
|
|
# 筛选我能参加的比赛
|
|
|
|
|
join = request.GET.get("join", None)
|
|
|
|
|
if join:
|
|
|
|
|
contests = Contest.objects.filter(Q(contest_type__in=[1, 2]) | Q(groups__in=request.user.group_set.all()))
|
|
|
|
|
|
2015-08-22 08:08:39 +00:00
|
|
|
|
paginator = Paginator(contests, 20)
|
|
|
|
|
try:
|
|
|
|
|
current_page = paginator.page(int(page))
|
|
|
|
|
except Exception:
|
|
|
|
|
return error_page(request, u"不存在的页码")
|
|
|
|
|
|
|
|
|
|
previous_page = next_page = None
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
previous_page = current_page.previous_page_number()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
next_page = current_page.next_page_number()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# 右侧的公告列表
|
|
|
|
|
announcements = Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time")
|
|
|
|
|
# 系统当前时间
|
|
|
|
|
now = datetime.datetime.now()
|
|
|
|
|
return render(request, "oj/contest/contest_list.html",
|
2015-08-22 12:42:21 +00:00
|
|
|
|
{"contests": current_page, "page": int(page),
|
2015-08-22 08:08:39 +00:00
|
|
|
|
"previous_page": previous_page, "next_page": next_page,
|
|
|
|
|
"keyword": keyword, "announcements": announcements,
|
Merge branch 'dev' into virusdefender-dev
* dev:
增加了比赛列表页
[后端]去掉了用于生产序号的javascript,改为使用模板过滤器实现(我的所有提交)
[前端]修改完善了添加比赛页面, 比赛列表功能仍不全面,稍后改进[CI SKIP]
修改了css引用方式[CI SKIP]
[后端]修改了contest中 api-docs 的小bug[CI SKIP]
创建前台比赛列表
去掉冗余语句,因为page变量已经有默认值了,不能为空
[后端]前台我的提交页面 增强提交序号的显示,原来是显示真实id即随机的散列值,不好看,现在改成自然数序列,但需要结合javascript生成,且是相对值,因为数据库里没有这个字段,有点别扭了. 第二,添加了用户没有提交记录的反馈. 第三,本打算增加筛选功能,但因为URL难以统一作罢,只有在增加新的url才能较好的处理,下次再说拜
[前端]比赛列表页面(后台)的进一步完善,不包含api
[后端]修改了我的提交列表的模板样式,整理格式
[后端]修改我的提交页面,去掉了冗余语句,并添加测试
[后端-前台]添加了submissions分页显示(只显示当前用户的提交),调用已有的view完成单个submission的显示.显示界面与问题分页显示统一.问题是id的显示.url:http://127.0.0.1:8000/my_submissions/
[前端]修改添加比赛页面,新增了使用小组api查询该用户所创建的所有的小组的功能[CI SKIP]
[ÂâçÁ´Ø]Ê∑ªÂä†ÊØî˵õÈ°µÈù¢Ëøõ‰∏ÄÊ≠•ÂÆåÂñÑ,Ê∑ªÂä†Â≠óÊƵÂåÖÊã¨ÊòØÂê¶ÊòæÁ§∫Êèê‰∫§,ÊØî˵õÊ®°Âºè,ÈóÆÈ¢òÂàÜÂĺ,ÂÖÅËÆ∏ÂèÇÂä†ÊØî˵õÁöÑÁî®Êà∑ÁªÑ,Âπ∂ÂÆåÂñÑÂÜÖÈÉ®ÈĪËæë,Âü∫Êú¨ÂèØÁ∫Ü,Âè™ÊòØÊ≤°ÂÜôajaxÊèê‰∫§Êï∞ÊçÆ,ÂíåÂïÊãâÂÂèñÂ∞èÁªÑ‰ø°ÊÅØÁöÑÈÉ®ÂàÜ[CI SKIP]
[前端]修改了添加比赛页的形式结构,仍有bug[CI SKIP]
Ê∑[ÂâçÁ´Ø]Ê∑ªÂä†ÊØîËÂêéÂè∞ÊØî˵õÂàóË°®[CI SKIP]
[ÂâçÁ´Ø]Áªü‰∏ÄÈóÆÈ¢òÈá,ÊØî˵õÂàóË°®jsÁöÑÊñቪ∂Âêç_list.js. Ê∑ªÂ䆉∫ÜÊØî˵õÂàóË°®ÂíåÁºñËæëÊØî˵õÁöÑÈ°µÈù¢(§߉Ωì§ʆ∑ºè)[CI SKIP]
Conflicts:
contest/views.py
2015-08-22 12:49:42 +00:00
|
|
|
|
"join": join, "now": now})
|