Accept Merge Request #185 为了比赛的一些修改,更新到dev中 : (hohoTT-dev -> dev)

Merge Request: 为了比赛的一些修改,更新到dev中
Created By: @hohoTT
Accepted By: @hohoTT
URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/185
This commit is contained in:
hohoTT 2015-09-07 21:34:43 +08:00
commit ad881fd291
13 changed files with 458 additions and 78 deletions

View File

@ -370,7 +370,7 @@ class UserLogoutTest(TestCase):
user.set_password("1") user.set_password("1")
user.save() user.save()
def logout_success(self): def test_logout_success(self):
self.client = Client() self.client = Client()
self.client.login(username="test", password="1") self.client.login(username="test", password="1")
response = self.client.get("/logout/") response = self.client.get("/logout/")

9
contest/test_urls.py Normal file
View File

@ -0,0 +1,9 @@
# coding=utf-8
from django.conf.urls import include, url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^login/$', TemplateView.as_view(template_name="oj/account/login.html"), name="user_login_page"),
]

View File

@ -1,15 +1,18 @@
# coding=utf-8 # coding=utf-8
import json import json
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase, Client
from django.http import HttpResponse
from rest_framework.test import APITestCase, APIClient from rest_framework.test import APITestCase, APIClient
from account.models import User from account.models import User
from group.models import Group from group.models import Group
from contest.models import Contest, ContestProblem from contest.models import Contest, ContestProblem
from .models import ContestSubmission
from announcement.models import Announcement from announcement.models import Announcement
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
from decorators import check_user_contest_permission
class ContestAdminAPITest(APITestCase): class ContestAdminAPITest(APITestCase):
@ -398,3 +401,181 @@ class ContestProblemAdminAPItEST(APITestCase):
response = self.client.put(self.url, data=data) response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1) self.assertEqual(response.data["code"], 1)
class ContestPasswordVerifyAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('contest_password_verify_api')
self.user = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user.set_password("testaa")
self.user.save()
self.user2 = User.objects.create(username="test2", admin_type=ADMIN)
self.user2.set_password("testbb")
self.user2.save()
self.client.login(username="test1", password="testaa")
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
def test_invalid_format(self):
self.client.login(username="test2", password="testbb")
data = {"contest_id": self.global_contest.id}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_contest_does_not_exist(self):
self.client.login(username="test2", password="testbb")
data = {"contest_id": self.global_contest.id + 1, "password": "aacc"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛不存在"})
def test_contest_password_verify_unsuccessfully(self):
self.client.login(username="test2", password="testbb")
data = {"contest_id": self.global_contest.id, "password": "aabb"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"密码错误"})
def test_contest_password_verify_successfully(self):
self.client.login(username="test2", password="testbb")
data = {"contest_id": self.global_contest.id, "password": "aacc"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
class ContestPageTest(TestCase):
# 单个比赛详情页的测试
def setUp(self):
self.client = Client()
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.client.login(username="test1", password="testaa")
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
def test_visit_contest_page_successfully(self):
response = self.client.get('/contest/1/')
self.assertEqual(response.status_code, 200)
def test_visit_contest_page_unsuccessfully(self):
response = self.client.get('/contest/10/')
self.assertTemplateUsed(response, "utils/error.html")
class ContestProblemPageTest(TestCase):
# 单个比赛题目详情页的测试
def setUp(self):
self.client = Client()
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.client.login(username="test1", password="testaa")
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
self.contest_problem = ContestProblem.objects.create(title="titlex",
description="descriptionx",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
hint="hint1",
created_by=User.objects.get(username="test1"),
contest=Contest.objects.get(title="titlex"),
sort_index="a")
def test_visit_contest_problem_page_successfully(self):
response = self.client.get('/contest/1/problem/1/')
self.assertEqual(response.status_code, 200)
def test_visit_contest_page_unsuccessfully(self):
response = self.client.get('/contest/10/')
self.assertTemplateUsed(response, "utils/error.html")
def test_visit_contest_submissions_page_successfully(self):
ContestSubmission.objects.create(user=self.user1,
contest=self.global_contest,
problem=self.contest_problem,
ac=True)
response = self.client.get('/contest/1/problem/1/submissions/')
self.assertEqual(response.status_code, 200)
class ContestProblemListPageTest(TestCase):
# 比赛题目列表的测试
def setUp(self):
self.client = Client()
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.client.login(username="test1", password="testaa")
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
self.contest_problem = ContestProblem.objects.create(title="titlex",
description="descriptionx",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
hint="hint1",
created_by=User.objects.get(username="test1"),
contest=Contest.objects.get(title="titlex"),
sort_index="a")
def test_visit_contest_problem_list_page_successfully(self):
response = self.client.get('/contest/1/problems/')
self.assertEqual(response.status_code, 200)
def test_visit_contest_problem_page_unsuccessfully(self):
response = self.client.get('/contest/1/problem/100/')
self.assertTemplateUsed(response, "utils/error.html")
class ContestListPageTest(TestCase):
# 以下是所有比赛列表页的测试
def setUp(self):
self.client = Client()
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.url = reverse('contest_list_page')
self.client.login(username="test1", password="testaa")
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
def test_visit_contest_list_page_successfully(self):
response = self.client.get('/contests/')
self.assertEqual(response.status_code, 200)
def test_visit_contest_list_page_unsuccessfully(self):
response = self.client.get('/contests/2/')
self.assertTemplateUsed(response, "utils/error.html")
def test_query_by_keyword(self):
response = self.client.get(self.url + "?keyword=title1")
self.assertEqual(response.status_code, 200)
def test_query_by_join_successfully(self):
response = self.client.get(self.url + "?join=True")
self.assertEqual(response.status_code, 200)

View File

@ -320,7 +320,6 @@ def contest_problems_list_page(request, contest_id):
contest = Contest.objects.get(id=contest_id) contest = Contest.objects.get(id=contest_id)
except Contest.DoesNotExist: except Contest.DoesNotExist:
return error_page(request, u"比赛不存在") return error_page(request, u"比赛不存在")
contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")
submissions = ContestSubmission.objects.filter(user=request.user, contest=contest) submissions = ContestSubmission.objects.filter(user=request.user, contest=contest)
state = {} state = {}
@ -334,10 +333,8 @@ def contest_problems_list_page(request, contest_id):
item.state = 2 item.state = 2
else: else:
item.state = 0 item.state = 0
# 右侧的公告列表 # 右侧的公告列表
announcements = Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time") announcements = Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time")
return render(request, "oj/contest/contest_problems_list.html", {"contest_problems": contest_problems, return render(request, "oj/contest/contest_problems_list.html", {"contest_problems": contest_problems,
"announcements": announcements, "announcements": announcements,
"contest": {"id": contest_id}}) "contest": {"id": contest_id}})

View File

@ -1,14 +1,97 @@
# coding=utf-8
import json import json
from django.test import TestCase, Client
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from account.models import User, ADMIN, SUPER_ADMIN from account.models import User, REGULAR_USER, ADMIN, SUPER_ADMIN
from problem.models import Problem
from contest.models import Contest, ContestProblem from contest.models import Contest, ContestProblem
from submission.models import Submission from submission.models import Submission
from rest_framework.test import APITestCase, APIClient from rest_framework.test import APITestCase, APIClient
# Create your tests here. class ContestSubmissionAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('contest_submission_api')
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.user2 = User.objects.create(username="test2", admin_type=REGULAR_USER)
self.user2.set_password("testbb")
self.user2.save()
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=1, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-30T12:00:00.000Z",
created_by=User.objects.get(username="test1"))
self.contest_problem = ContestProblem.objects.create(title="titlex",
description="descriptionx",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
hint="hint1",
created_by=User.objects.get(username="test1"),
contest=Contest.objects.get(title="titlex"),
sort_index="a")
# 以下是创建比赛的提交
def test_invalid_format(self):
self.client.login(username="test1", password="testaa")
data = {"contest_id": self.global_contest.id, "language": 1}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_contest_submission_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"contest_id": self.global_contest.id, "problem_id": self.contest_problem.id,
"language": 1, "code": '#include "stdio.h"\nint main(){\n\treturn 0;\n}'}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_contest_problem_does_not_exist(self):
self.client.login(username="test1", password="testaa")
data = {"contest_id": self.global_contest.id, "problem_id": self.contest_problem.id + 10,
"language": 1, "code": '#include "stdio.h"\nint main(){\n\treturn 0;\n}'}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"题目不存在"})
class ContestProblemMySubmissionListTest(TestCase):
# 以下是我比赛单个题目的提交列表的测试
def setUp(self):
self.client = Client()
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.user2 = User.objects.create(username="test2", admin_type=REGULAR_USER)
self.user2.set_password("testbb")
self.user2.save()
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=1, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-30T12:00:00.000Z",
created_by=User.objects.get(username="test1"))
self.contest_problem = ContestProblem.objects.create(title="titlex",
description="descriptionx",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
hint="hint1",
created_by=self.user1,
contest=self.global_contest,
sort_index="a")
def test_contestsList_page_not_exist(self):
self.client.login(username="test1", password="testaa")
response = self.client.get('/contest/1/submissions/999/')
self.assertTemplateUsed(response, "utils/error.html")
class SubmissionAPITest(APITestCase): class SubmissionAPITest(APITestCase):
def setUp(self): def setUp(self):

View File

@ -1,6 +1,5 @@
# coding=utf-8 # coding=utf-8
import json import json
import redis import redis
from django.shortcuts import render from django.shortcuts import render
from django.core.paginator import Paginator from django.core.paginator import Paginator
@ -9,16 +8,15 @@ from rest_framework.views import APIView
from judge.judger_controller.tasks import judge from judge.judger_controller.tasks import judge
from judge.judger_controller.settings import redis_config from judge.judger_controller.settings import redis_config
from account.decorators import login_required from account.decorators import login_required
from account.models import SUPER_ADMIN from account.models import SUPER_ADMIN
from contest.decorators import check_user_contest_permission from contest.decorators import check_user_contest_permission
from problem.models import Problem from problem.models import Problem
from contest.models import Contest, ContestProblem from contest.models import Contest, ContestProblem
from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate
from submission.models import Submission from submission.models import Submission
from .serializers import CreateContestSubmissionSerializer from .serializers import CreateContestSubmissionSerializer
from submission.serializers import SubmissionSerializer from submission.serializers import SubmissionSerializer
@ -35,31 +33,24 @@ class ContestSubmissionAPIView(APIView):
serializer = CreateContestSubmissionSerializer(data=request.data) serializer = CreateContestSubmissionSerializer(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
data = serializer.data data = serializer.data
try: contest = Contest.objects.get(id=data["contest_id"])
contest = Contest.objects.get(id=data["contest_id"])
except Contest.DoesNotExist:
return error_response(u"比赛不存在")
try: try:
problem = ContestProblem.objects.get(contest=contest, id=data["problem_id"]) problem = ContestProblem.objects.get(contest=contest, id=data["problem_id"])
# 更新题目提交计数器 # 更新题目提交计数器
problem.total_submit_number += 1 problem.total_submit_number += 1
problem.save() problem.save()
except Problem.DoesNotExist: except ContestProblem.DoesNotExist:
return error_response(u"题目不存在") return error_response(u"题目不存在")
submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]),
contest_id=contest.id, code=data["code"], problem_id=problem.id) contest_id=contest.id, code=data["code"], problem_id=problem.id)
try: try:
judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id) judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id)
except Exception: except Exception:
return error_response(u"提交判题任务失败") return error_response(u"提交判题任务失败")
# 增加redis 中判题队列长度的计数器 # 增加redis 中判题队列长度的计数器
r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"]) r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"])
r.incr("judge_queue_length") r.incr("judge_queue_length")
return success_response({"submission_id": submission.id}) return success_response({"submission_id": submission.id})
else: else:
return serializer_invalid_response(serializer) return serializer_invalid_response(serializer)
@ -75,7 +66,7 @@ def contest_problem_my_submissions_list_page(request, contest_id, contest_proble
return error_page(request, u"比赛不存在") return error_page(request, u"比赛不存在")
try: try:
contest_problem = ContestProblem.objects.get(id=contest_problem_id, visible=True) contest_problem = ContestProblem.objects.get(id=contest_problem_id, visible=True)
except Problem.DoesNotExist: except ContestProblem.DoesNotExist:
return error_page(request, u"比赛问题不存在") return error_page(request, u"比赛问题不存在")
submissions = Submission.objects.filter(user_id=request.user.id, problem_id=contest_problem.id).order_by( submissions = Submission.objects.filter(user_id=request.user.id, problem_id=contest_problem.id).order_by(
"-create_time"). \ "-create_time"). \
@ -95,8 +86,26 @@ def contest_problem_submissions_list_page(request, contest_id, page=1):
return error_page(request, u"比赛不存在") return error_page(request, u"比赛不存在")
# 以下是本场比赛中所有的提交 # 以下是本场比赛中所有的提交
submissions = Submission.objects.filter(contest_id=contest_id). \ submissions = Submission.objects.filter(contest_id=contest_id). \
values("id", "result", "create_time", "accepted_answer_time", "language", "user_id").order_by("-create_time") values("id", "contest_id", "problem_id", "result", "create_time", "accepted_answer_time", "language", "user_id").order_by("-create_time")
language = request.GET.get("language", None)
filter = None
if language:
submissions = submissions.filter(language=int(language))
filter = {"name": "language", "content": language}
result = request.GET.get("result", None)
if result:
submissions = submissions.filter(result=int(result))
filter = {"name": "result", "content": result}
paginator = Paginator(submissions, 20) paginator = Paginator(submissions, 20)
# 为查询题目标题创建新字典
title = {}
contest_problems = ContestProblem.objects.filter(contest=contest)
for item in contest_problems:
title[item.id] = item.title
for item in submissions:
item['title'] = title[item['problem_id']]
try: try:
current_page = paginator.page(int(page)) current_page = paginator.page(int(page))
except Exception: except Exception:
@ -110,11 +119,10 @@ def contest_problem_submissions_list_page(request, contest_id, page=1):
next_page = current_page.next_page_number() next_page = current_page.next_page_number()
except Exception: except Exception:
pass pass
return render(request, "oj/contest/submissions_list.html", return render(request, "oj/contest/submissions_list.html",
{"submissions": current_page, "page": int(page), {"submissions": current_page, "page": int(page),
"previous_page": previous_page, "next_page": next_page, "start_id": int(page) * 20 - 20, "previous_page": previous_page, "next_page": next_page, "start_id": int(page) * 20 - 20,
"contest": contest}) "contest": contest, "filter":filter})
class ContestSubmissionAdminAPIView(APIView): class ContestSubmissionAdminAPIView(APIView):
@ -147,5 +155,4 @@ class ContestSubmissionAdminAPIView(APIView):
return error_response(u"参数错误!") return error_response(u"参数错误!")
if problem_id: if problem_id:
submissions = submissions.filter(problem_id=problem_id) submissions = submissions.filter(problem_id=problem_id)
return paginate(request, submissions, SubmissionSerializer)
return paginate(request, submissions, SubmissionSerializer)

View File

@ -187,5 +187,19 @@ class ProblemListPageTest(TestCase):
hint="hint1", hint="hint1",
created_by=User.objects.get(username="test")) created_by=User.objects.get(username="test"))
def test_problemListPage_not_exist(self):
response = self.client.get('/problems/999/')
self.assertTemplateUsed(response, "utils/error.html")
def test_query_by_keyword(self):
response = self.client.get(self.url + "?keyword=title1")
self.assertEqual(response.status_code, 200)
def test_query_by_tag_successfully(self):
response = self.client.get(self.url + "?tag=")
self.assertEqual(response.status_code, 200)
def test_tag_does_not_exists(self):
response = self.client.get(self.url + "?tag=xxxxxx")
self.assertTemplateUsed(response, "utils/error.html")

View File

@ -1,6 +1,6 @@
# coding=utf-8 # coding=utf-8
import json import json
from django.test import TestCase from django.test import TestCase, Client
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from account.models import User, REGULAR_USER, ADMIN, SUPER_ADMIN from account.models import User, REGULAR_USER, ADMIN, SUPER_ADMIN
from problem.models import Problem from problem.models import Problem
@ -11,7 +11,7 @@ from rest_framework.test import APITestCase, APIClient
class SubmissionsListPageTest(TestCase): class SubmissionsListPageTest(TestCase):
def setUp(self): def setUp(self):
self.client = APIClient() self.client = Client()
self.user = User.objects.create(username="gogoing", admin_type=REGULAR_USER) self.user = User.objects.create(username="gogoing", admin_type=REGULAR_USER)
self.user2 = User.objects.create(username="cool", admin_type=REGULAR_USER) self.user2 = User.objects.create(username="cool", admin_type=REGULAR_USER)
self.user2.set_password("666666") self.user2.set_password("666666")
@ -124,25 +124,78 @@ class SubmissionAPITest(APITestCase):
response = self.client.get(self.url, data=data) response = self.client.get(self.url, data=data)
self.assertEqual(response.data["code"], 0) self.assertEqual(response.data["code"], 0)
def test_parameter_error(self):
self.client.login(username="test1", password="testaa")
response = self.client.get(self.url)
self.assertEqual(response.data, {"code": 1, "data": u"参数错误"})
class ContestSubmissionAPITest(APITestCase):
class SubmissionAdminAPITest(APITestCase):
def setUp(self): def setUp(self):
self.client = APIClient() self.client = APIClient()
self.url = reverse('contest_submission_api') self.url = reverse('submission_admin_api_view')
self.user1 = User.objects.create(username="test1", admin_type=REGULAR_USER) self.user = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa") self.user.set_password("testaa")
self.user1.save() self.user.save()
self.user2 = User.objects.create(username="test2", admin_type=SUPER_ADMIN) self.client.login(username="test1", password="testaa")
self.user2.set_password("testbb") self.problem = Problem.objects.create(title="title1",
self.user2.save() description="description1",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
source="source1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
difficulty=1,
hint="hint1",
created_by=self.user)
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1, self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True, contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z", start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z", end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test2")) password="aacc", created_by=self.user)
self.submission = Submission.objects.create(user_id=self.user.id,
language=1,
code='#include "stdio.h"\nint main(){\n\treturn 0;\n}',
problem_id=self.problem.id)
def test_invalid_format(self): def test_invalid_format(self):
response = self.client.get(self.url)
self.assertEqual(response.data, {"code": 1, "data": u"参数错误"})
class SubmissionPageTest(TestCase):
# 单个题目的提交详情页
def setUp(self):
self.client = Client()
self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user1.set_password("testaa")
self.user1.save()
self.user2 = User.objects.create(username="test2", admin_type=ADMIN)
self.user2.set_password("testbb")
self.user2.save()
self.client.login(username="test1", password="testaa") self.client.login(username="test1", password="testaa")
data = {"language": 1} self.problem = Problem.objects.create(title="title1",
response = self.client.post(self.url, data=data) description="description1",
pass input_description="input1_description",
output_description="output1_description",
test_case_id="1",
source="source1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
difficulty=1,
hint="hint1",
created_by=User.objects.get(username="test1"))
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
self.submission = Submission.objects.create(user_id=self.user1.id,
language=1,
code='#include "stdio.h"\nint main(){\n\treturn 0;\n}',
problem_id=self.problem.id)

View File

@ -139,7 +139,7 @@ def my_submission_list_page(request, page=1):
我的所有提交的列表页 我的所有提交的列表页
""" """
submissions = Submission.objects.filter(user_id=request.user.id, contest_id__isnull=True). \ submissions = Submission.objects.filter(user_id=request.user.id, contest_id__isnull=True). \
values("id", "result", "create_time", "accepted_answer_time", "language").order_by("-create_time") values("id", "problem_id", "result", "create_time", "accepted_answer_time", "language").order_by("-create_time")
language = request.GET.get("language", None) language = request.GET.get("language", None)
filter = None filter = None
if language: if language:

View File

@ -18,17 +18,19 @@
<tr class="" success> <tr class="" success>
<th>#</th> <th>#</th>
<th>提交时间</th> <th>提交时间</th>
<th>结果</th>
<th>运行时间</th>
<th>语言</th> <th>语言</th>
<th>运行时间</th>
<th>结果</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in submissions %} {% for item in submissions %}
<tr class="{{ item.result|translate_result_class }}"> <tr>
<th scope="row"><a href="/submission/{{ item.id }}/">{{ forloop.counter }}</a></th> <th scope="row"><a href="/submission/{{ item.id }}/">{{ forloop.counter }}</a></th>
<td>{{ item.create_time }}</td> <td>{{ item.create_time }}</td>
<td>{{ item.result|translate_result }}</td> <td>
{{ item.language|translate_language }}
</td>
<td> <td>
{% if item.accepted_answer_time %} {% if item.accepted_answer_time %}
{{ item.accepted_answer_time }}ms {{ item.accepted_answer_time }}ms
@ -36,8 +38,8 @@
-- --
{% endif %} {% endif %}
</td> </td>
<td> <td class="alert-{{ item.result|translate_result_class }}">
{{ item.language|translate_language }} <strong>{{ item.result|translate_result }}</strong>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -26,28 +26,61 @@
<thead> <thead>
<tr class="" success> <tr class="" success>
<th>#</th> <th>#</th>
<td>用户</td> <th>题目名称</th>
<th>用户</th>
<th>提交时间</th> <th>提交时间</th>
<th>结果</th> <th>
<div class="dropdown">
<a href="#" class="dropdown-toggle" id="languageFilter" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true">
语言<span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="languageFilter">
<li><a href="/contest/{{ contest.id }}/submissions/?language=1">C</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?language=2">C++</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?language=3">Java</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/">取消筛选</a></li>
</ul>
</div>
</th>
<th>运行时间</th> <th>运行时间</th>
<th>语言</th> <th>
<div class="dropdown">
<a href="#" class="dropdown-toggle" id="resultFilter" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true">
结果<span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="resultFilter">
<li><a href="/contest/{{ contest.id }}/submissions/?result=0">Accepted</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?result=6">Wrong Answer</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?result=1">Runtime Error</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?result=2">Time Limit Exceeded</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?result=3">Memory Limit Exceeded</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?result=4">Compile Error</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/?result=5">Format Error</a></li>
<li><a href="/contest/{{ contest.id }}/submissions/">取消筛选</a></li>
</ul>
</div>
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in submissions %} {% for item in submissions %}
<tr class="{{ item.result|translate_result_class }}"> <tr>
{% ifequal item.user_id request.user.id %} {% ifequal item.user_id request.user.id %}
<th scope="row"><a href="/submission/{{ item.id }}/" id="id_{{ forloop.counter }}"> <th scope="row"><a href="/submission/{{ item.id }}/">
{{ forloop.counter |add:start_id }}</a></th> {{ forloop.counter |add:start_id }}</a></th>
{% else %} {% else %}
<th scope="row">{{ forloop.counter |add:start_id }}</th> <th scope="row">{{ forloop.counter |add:start_id }}</th>
{% endifequal %} {% endifequal %}
<th scope="row">
<a href="/contest/{{ item.contest_id }}/problem/{{ item.problem_id }}/">{{ item.title }}</a>
</th>
<td>{{ item.user_id|get_username }}</td> <td>{{ item.user_id|get_username }}</td>
<td>{{ item.create_time }}</td> <td>{{ item.create_time }}</td>
<td>{{ item.result|translate_result }}</td> <td>
{{ item.language|translate_language }}
</td>
<td> <td>
{% if item.accepted_answer_time %} {% if item.accepted_answer_time %}
{{ item.accepted_answer_time }}ms {{ item.accepted_answer_time }}ms
@ -55,12 +88,11 @@
-- --
{% endif %} {% endif %}
</td> </td>
<td> <td class="alert-{{ item.result|translate_result_class }}">
{{ item.language|translate_language }} <strong>{{ item.result|translate_result }}</strong>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
@ -70,15 +102,15 @@
<ul class="pager"> <ul class="pager">
{% if previous_page %} {% if previous_page %}
<li class="previous"><a <li class="previous"><a
href="/contest/{{ contest.id }}/submissions/{{ previous_page }}/"> href="/contest/{{ contest.id }}/submissions/{{ previous_page }}/{% if filter %}?{{ filter.name }}={{ filter.content }}{% endif %}">
<span aria-hidden="true">&larr;</span> 上一页</a></li> <span aria-hidden="true">&larr;</span> 上一页</a></li>
{% endif %} {% endif %}
{% if next_page %} {% if next_page %}
<li class="next"> <li class="next">
<a href="/contest/{{ contest.id }}/submissions/{{ next_page }}/">下一页 <span <a href="/contest/{{ contest.id }}/submissions/{{ next_page }}/{% if filter %}?{{ filter.name }}={{ filter.content }}{% endif %}">
aria-hidden="true">&rarr;</span></a></li> 下一页 <span aria-hidden="true">&rarr;</span></a></li>
{% endif %} {% endif %}
</ul> </ul>
</nav> </nav>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -4,8 +4,14 @@
<div class="container main"> <div class="container main">
<ul class="nav nav-tabs nav-tabs-google"> <ul class="nav nav-tabs nav-tabs-google">
<li role="presentation" class="active"> <li role="presentation" class="active">
<a href="/problem/{{ problem.id }}/">题目</a></li> <a href="/problem/{{ problem.id }}/">题目</a>
<li role="presentation"><a href="/problem/{{ problem.id }}/submissions/">我的提交</a></li> </li>
<li role="presentation">
<a href="/problem/{{ problem.id }}/submissions/">我的提交</a>
</li>
<li role="presentation">
<a href="/problems/">返回</a>
</li>
</ul> </ul>
{% include "oj/problem/_problem_header.html" %} {% include "oj/problem/_problem_header.html" %}
@ -33,7 +39,6 @@
</div> </div>
<div class="problem-section"> <div class="problem-section">
<label class="problem-label">样例输出{{ forloop.counter }}</label> <label class="problem-label">样例输出{{ forloop.counter }}</label>
<pre> <pre>
{{ item.output }}</pre> {{ item.output }}</pre>
@ -45,23 +50,19 @@
{% if problem.hint %} {% if problem.hint %}
<div class="problem-section hide"> <div class="problem-section hide">
<label class="problem-label">提示</label> <label class="problem-label">提示</label>
<p class="problem-detail">{{ problem.hint|safe }}</p> <p class="problem-detail">{{ problem.hint|safe }}</p>
</div> </div>
{% endif %} {% endif %}
<div class="problem-section hide"> <div class="problem-section hide">
<label class="problem-label">标签</label> <label class="problem-label">标签</label>
<p class="problem-detail"> <p class="problem-detail">
{% for tag in problem.tags.all %} {% for tag in problem.tags.all %}
<span class="label label-success">{{ tag.name }}</span> <span class="label label-success">{{ tag.name }}</span>
{% endfor %} {% endfor %}
</p> </p>
</div> </div>
<div> <div>
<label>选择语言</label> <label>选择语言</label>
<div> <div>
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" name="language" value="1" checked> C (gcc 4.8) <input type="radio" name="language" value="1" checked> C (gcc 4.8)
@ -74,7 +75,6 @@
</label> </label>
</div> </div>
</div> </div>
<div id="code-field"> <div id="code-field">
<label class="problem-label">提交代码</label> <label class="problem-label">提交代码</label>
<textarea id="code-editor"></textarea> <textarea id="code-editor"></textarea>
@ -85,9 +85,7 @@
提交代码 提交代码
</button> </button>
<img src="/static/img/loading.gif" id="loading-gif"> <img src="/static/img/loading.gif" id="loading-gif">
</div> </div>
<div id="result"> <div id="result">
</div> </div>
<hr> <hr>

View File

@ -1,7 +1,6 @@
{% extends 'oj_base.html' %} {% extends 'oj_base.html' %}
{% block body %} {% block body %}
{% load submission %} {% load submission %}
<div class="container main"> <div class="container main">
<div class="col-md-9 col-lg-9"> <div class="col-md-9 col-lg-9">
@ -9,6 +8,7 @@
<thead> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
<th>题目名称</th>
<th>提交时间</th> <th>提交时间</th>
<th> <th>
<div class="dropdown"> <div class="dropdown">
@ -48,8 +48,12 @@
<tbody> <tbody>
{% for item in submissions %} {% for item in submissions %}
<tr> <tr>
<th scope="row"><a href="/submission/{{ item.id }}/" id="id_{{ forloop.counter }}"> <th scope="row">
{{ forloop.counter |add:start_id }}</a></th> <a href="/submission/{{ item.id }}/">{{ forloop.counter |add:start_id }}</a>
</th>
<td>
<a href="/problem/{{ item.problem_id }}/">{{ item.problem_id }}</a>
</td>
<td>{{ item.create_time }}</td> <td>{{ item.create_time }}</td>
<td> <td>
{{ item.language|translate_language }} {{ item.language|translate_language }}
@ -92,4 +96,4 @@
{% include "oj/announcement/_announcement_panel.html" %} {% include "oj/announcement/_announcement_panel.html" %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}