mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 00:13:18 +00:00
Merge branch 'hohoTT-dev' into virusdefender-dev
* hohoTT-dev: 添加前台比赛题目列表与单个题目的页面 Conflicts: submission/views.py
This commit is contained in:
commit
3251b9bf08
@ -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})
|
||||
|
||||
|
||||
|
||||
|
||||
|
11
oj/urls.py
11
oj/urls.py
@ -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(),
|
||||
|
@ -7,13 +7,16 @@ from django.core.paginator import Paginator
|
||||
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from problem.models import Problem
|
||||
from judge.judger_controller.tasks import judge
|
||||
from judge.judger_controller.settings import redis_config
|
||||
from account.decorators import login_required
|
||||
from account.models import SUPER_ADMIN
|
||||
from contest.models import Contest, ContestProblem
|
||||
|
||||
from contest.decorators import check_user_contest_permission
|
||||
|
||||
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, CreateContestSubmissionSerializer
|
||||
@ -80,6 +83,23 @@ 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:
|
||||
@ -139,9 +159,8 @@ def my_submission_list_page(request, page=1):
|
||||
"previous_page": previous_page, "next_page": next_page, "start_id": int(page) * 20 - 20})
|
||||
|
||||
|
||||
|
||||
class ContestSubmissionAPIView(APIView):
|
||||
@check_user_contest_permission
|
||||
# @check_user_contest_permission
|
||||
def post(self, request):
|
||||
"""
|
||||
创建比赛的提交
|
||||
|
100
template/oj/contest/contest_problem.html
Normal file
100
template/oj/contest/contest_problem.html
Normal 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 }}
|
||||
时间限制 : {{ contest_problem.time_limit }}ms
|
||||
内存限制 : {{ 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 %}
|
64
template/oj/contest/contest_problems_list.html
Normal file
64
template/oj/contest/contest_problems_list.html
Normal 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">←</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">→</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 %}
|
52
template/oj/contest/my_submissions_list.html
Normal file
52
template/oj/contest/my_submissions_list.html
Normal 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 }}
|
||||
时间限制: {{ contest_problem.time_limit }}ms
|
||||
内存限制: {{ 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 %}
|
@ -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>
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user