添加前台比赛题目列表与单个题目的页面

This commit is contained in:
hohoTT 2015-08-23 18:25:28 +08:00
parent 86d33dd974
commit 4d701e0239
8 changed files with 280 additions and 8 deletions

View File

@ -263,6 +263,31 @@ def contest_page(request, contest_id):
return render(request, "oj/contest/contest_index.html", {"contest": contest})
def contest_problem_page(request, contest_id, contest_problem_id):
try:
Contest.objects.get(id=contest_id)
except Contest.DoesNotExist:
return error_page(request, u"比赛不存在")
try:
contest_problem = ContestProblem.objects.get(id=contest_problem_id, visible=True)
except ContestProblem.DoesNotExist:
return error_page(request, u"比赛题目不存在")
return render(request, "oj/contest/contest_problem.html", {"contest_problem": contest_problem,
"samples": json.loads(contest_problem.samples)})
@check_user_contest_permission
def contest_problems_list_page(request, contest_id):
try:
contest_problems = ContestProblem.objects.filter(contest=Contest.objects.get(id=contest_id)).order_by("sort_index")
except Contest.DoesNotExist:
return error_page(request, u"比赛题目不存在")
# 右侧的公告列表
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,
"announcements": announcements})
def contest_list_page(request, page=1):
# 正常情况
contests = Contest.objects.filter(visible=True)
@ -298,10 +323,13 @@ def contest_list_page(request, page=1):
# 右侧的公告列表
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",
{"contests": current_page, "page": int(page),
"previous_page": previous_page, "next_page": next_page,
"keyword": keyword, "announcements": announcements,
"join": join, "now": now})
"join": join})

View File

@ -40,7 +40,14 @@ urlpatterns = [
url(r'^api/admin/contest/$', ContestAdminAPIView.as_view(), name="contest_admin_api"),
url(r'^api/admin/user/$', UserAdminAPIView.as_view(), name="user_admin_api"),
url(r'^problem/(?P<problem_id>\d+)/$', "problem.views.problem_page", name="problem_page"),
url(r'^problem/(?P<problem_id>\d+)/$', "problem.views.problem_page", name="problem_page"),
url(r'^contest/(?P<contest_id>\d+)/problem/(?P<contest_problem_id>\d+)/$', "contest.views.contest_problem_page",
name="contest_problem_page"),
url(r'^contest/(?P<contest_id>\d+)/$', "contest.views.contest_page", name="contest_page"),
url(r'^contest/(?P<contest_id>\d+)/problems/$', "contest.views.contest_problems_list_page",
name="contest_problems_list_page"),
url(r'^announcement/(?P<announcement_id>\d+)/$', "announcement.views.announcement_page",
name="announcement_page"),
url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"),
@ -60,6 +67,10 @@ urlpatterns = [
url(r'^api/admin/tag/$', ProblemTagAdminAPIView.as_view(), name="problem_tag_admin_api"),
url(r'^problem/(?P<problem_id>\d+)/my_submissions/$', "submission.views.problem_my_submissions_list_page",
name="problem_my_submissions_page"),
url(r'^contest/(?P<contest_id>\d+)/problem/(?P<contest_problem_id>\d+)/my_submissions/$',
"submission.views.contest_problem_my_submissions_list_page", name="contest_problem_my_submissions_list_page"),
url(r'^my_submission/(?P<submission_id>\w+)/$', "submission.views.my_submission", name="my_submission_page"),
url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(),

View File

@ -12,6 +12,7 @@ from judge.judger_controller.settings import redis_config
from account.decorators import login_required
from account.models import SUPER_ADMIN
from problem.models import Problem
from contest.models import Contest, ContestProblem
from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate
from .models import Submission
from .serializers import CreateSubmissionSerializer, SubmissionSerializer
@ -79,6 +80,22 @@ def problem_my_submissions_list_page(request, problem_id):
{"submissions": submissions, "problem": problem})
@login_required
def contest_problem_my_submissions_list_page(request, contest_id, contest_problem_id):
try:
Contest.objects.get(id=contest_id)
except Contest.DoesNotExist:
return error_page(request, u"比赛不存在")
try:
contest_problem = ContestProblem.objects.get(id=contest_problem_id, visible=True)
except Problem.DoesNotExist:
return error_page(request, u"比赛问题不存在")
submissions = Submission.objects.filter(user_id=request.user.id, problem_id=contest_problem.id).order_by("-create_time"). \
values("id", "result", "create_time", "accepted_answer_time", "language")
return render(request, "oj/contest/my_submissions_list.html",
{"submissions": submissions, "contest_problem": contest_problem})
@login_required
def my_submission(request, submission_id):
try:

View File

@ -0,0 +1,100 @@
{% extends 'oj_base.html' %}
{% block body %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation" class="active">
<a href="/contest/{{ contest_problem.contest.id }}/problem/{{ contest_problem.id }}/">题目</a></li>
<li role="presentation"><a href="/contest/{{ contest_problem.contest.id }}/problem/{{ contest_problem.id }}/my_submissions/">我的提交</a></li>
</ul>
<h2 class="text-center">{{ contest_problem.title }}</h2>
<p class="text-muted text-center">发布时间 : {{ contest_problem.create_time }}&nbsp;&nbsp;
时间限制 : {{ contest_problem.time_limit }}ms&nbsp;&nbsp;
内存限制 : {{ contest_problem.memory_limit }}M
</p>
<div>
<div class="problem-section">
<label class="problem-label">描述</label>
<p class="problem-detail">{{ contest_problem.description|safe }}</p>
</div>
<div class="problem-section">
<label class="problem-label">输入</label>
<p class="problem-detail">{{ contest_problem.input_description }}</p>
</div>
<div class="problem-section">
<label class="problem-label">输出</label>
<p class="problem-detail">{{ contest_problem.output_description }}k</p>
</div>
{% for item in samples %}
<div class="problem-section">
<label class="problem-label">样例输入{{ forloop.counter }}</label>
<pre>
{{ item.input }}</pre>
</div>
<div class="problem-section">
<label class="problem-label">样例输出{{ forloop.counter }}</label>
<pre>
{{ item.output }}</pre>
</div>
{% endfor %}
{% if problem.hint %}
<div class="problem-section hide">
<label class="problem-label">提示</label>
<p class="problem-detail">{{ contest_problem.hint|safe }}</p>
</div>
{% endif %}
{% if contest_problem.hint %}
<div class="problem-section hide">
<label class="problem-label">提示</label>
<p class="problem-detail">{{ contest_problem.hint|safe }}</p>
</div>
{% endif %}
<div>
<label>选择语言</label>
<div>
<label class="radio-inline">
<input type="radio" name="language" value="1" checked> C (gcc 4.8)
</label>
<label class="radio-inline">
<input type="radio" name="language" value="2"> C++ (g++ 4.3)
</label>
<label class="radio-inline">
<input type="radio" name="language" value="3"> Java (jre 1.7)
</label>
</div>
</div>
<div id="code-field">
<label class="problem-label">提交代码</label>
<textarea id="code-editor"></textarea>
</div>
<hr>
<div id="submit-code">
<button type="button" class="btn btn-primary" id="submit-code-button">
提交代码
</button>
<img src="/static/img/loading.gif" id="loading-gif">
</div>
<div id="result">
</div>
<hr>
</div>
</div>
{% endblock %}
{% block js_block %}
<script src="/static/js/app/oj/problem/problem.js"></script>
{% endblock %}

View File

@ -0,0 +1,64 @@
{% extends "oj_base.html" %}
{% block body %}
{% load problem %}
<div class="container main">
<div class="row">
<div class="col-lg-9">
<div class="row">
<div class="right">
<form class="form-inline" method="get">
<div class="form-group-sm">
<input name="keyword" class="form-control" placeholder="请输入关键词">
<input type="submit" value="搜索" class="btn btn-primary">
</div>
</form>
</div>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th>#</th>
<th>题目</th>
<th>通过率</th>
</tr>
</thead>
<tbody>
{% for item in contest_problems %}
<tr>
<th><span class="glyphicon glyphicon-ok ac-flag"></span></th>
<th scope="row"><a href="/contest/{{ item.contest.id }}/problem/{{ item.id }}/">{{ item.sort_index }}</a></th>
<td><a href="/contest/{{ item.contest.id }}/problem/{{ item.id }}/">{{ item.title }}</a></td>
<td>{{ item|accepted_radio }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav>
<ul class="pager">
{% if previous_page %}
<li class="previous"><a
href="/problems/{{ previous_page }}/{% if keyword %}?keyword={{ keyword }}{% endif %}{% if tag %}?tag={{ tag }}{% endif %}">
<span aria-hidden="true">&larr;</span> 上一页</a></li>
{% endif %}
{% if next_page %}
<li class="next"><a
href="/problems/{{ next_page }}/{% if keyword %}?keyword={{ keyword }}{% endif %}{% if tag %}?tag={{ tag }}{% endif %}">下一页 <span
aria-hidden="true">&rarr;</span></a></li>
{% endif %}
</ul>
</nav>
</div>
</div>
<div class="col-lg-3">
{% include "oj/announcement/_announcement_panel.html" %}
</div>
</div>
</div>
{% endblock %}
{% block js_block %}
<script src="/static/js/app/oj/problem/problem_list.js"></script>
{% endblock %}

View File

@ -0,0 +1,52 @@
{% extends 'oj_base.html' %}
{% block body %}
{% load submission %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation">
<a href="/contest/{{ contest_problem.contest.id }}/problem/{{ contest_problem.id }}/">题目</a></li>
<li role="presentation" class="active">
<a href="/contest/{{ contest_problem.contest.id }}/problem/{{ contest_problem.id }}/my_submissions/">
我的提交</a>
</li>
</ul>
<h2 class="text-center">{{ contest_problem.title }}</h2>
<p class="text-muted text-center">发布时间: {{ contest_problem.create_time }}&nbsp;&nbsp;
时间限制: {{ contest_problem.time_limit }}ms&nbsp;&nbsp;
内存限制: {{ contest_problem.memory_limit }}M</p>
<table class="table table-bordered">
<thead>
<tr class="" success>
<th>#</th>
<th>提交时间</th>
<th>结果</th>
<th>运行时间</th>
<th>语言</th>
</tr>
</thead>
<tbody>
{% for item in submissions %}
<tr class="{{ item.result|translate_result_class }}">
<th scope="row"><a href="/my_submission/{{ item.id }}/">{{ forloop.counter }}</a></th>
<td>{{ item.create_time }}</td>
<td>{{ item.result|translate_result }}</td>
<td>
{% if item.accepted_answer_time %}
{{ item.accepted_answer_time }}ms
{% else %}
--
{% endif %}
</td>
<td>
{{ item.language|translate_language }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -32,7 +32,7 @@
<th scope="row"><a href="/problem/{{ item.id }}/">{{ item.id }}</a></th>
<td><a href="/problem/{{ item.id }}/">{{ item.title }}</a></td>
<td>{{ item.difficulty }}</td>
<td>{{ item|accepted_radio }}%</td>
<td>{{ item|accepted_radio }}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -2,13 +2,13 @@
def get_problem_accepted_radio(problem):
if problem.total_accepted_number:
return int((problem.total_accepted_number * 100) / problem.total_submit_number)
return 0
if problem.total_submit_number:
return str(int((problem.total_accepted_number * 100) / problem.total_submit_number)) \
+ "% (" + str(problem.total_accepted_number) + "/" + str(problem.total_submit_number) + ")"
return "0%"
from django import template
register = template.Library()
register.filter("accepted_radio", get_problem_accepted_radio)