Merge branch 'hohoTT-dev' into dev

* hohoTT-dev:
  后端比赛与比赛题目部分已修改完成
  修改并完善比赛及其他部分的内容及测试
  CodeMirror自动更改高度的问题
  增加及修改account与announcement的测试
  修改比赛的views及部分问题
  后端修改比赛创建部分,同时在models中增加了几个字段
  后端比赛和比赛题目的部分,还有要增加和修改的地方
  修复一个点击错误

Conflicts:
	static/src/css/oj.css
This commit is contained in:
virusdefender 2015-08-22 14:12:14 +08:00
commit ea3e8841a9
20 changed files with 1009 additions and 78 deletions

View File

@ -130,7 +130,7 @@ class UserChangePasswordAPITest(APITestCase):
self.assertEqual(response.data, {"code": 1, "data": u"密码不正确,请重新修改!"})
def test_invalid_data_format(self):
data = {"username": "test", "old_password": "aaa", "new_password": "aaaddd"}
data = {"old_password": "aaa", "new_password": "aaaddd"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
@ -152,15 +152,50 @@ class UserAdminAPITest(APITestCase):
user = User.objects.create(username="testx", real_name="xx", admin_type=SUPER_ADMIN)
user.set_password("testxx")
user.save()
user = User.objects.create(username="testy", real_name="yy", admin_type=SUPER_ADMIN)
user.set_password("testyy")
user.save()
self.client.login(username="testx", password="testxx")
# 以下是编辑用户的测试
def test_success_get_data(self):
self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_put_invalid_data(self):
data = {"username": "test", "password": "testaa", "email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_user_does_not_exist(self):
data = {"id": 3, "username": "test0", "real_name": "test00",
"password": "testaa", "email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该用户不存在!"})
def test_username_exists(self):
data = {"id": 1, "username": "testy", "real_name": "test00",
"password": "testaa", "email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"昵称已经存在"})
def test_user_edit_not_password_successfully(self):
data = {"id": 1, "username": "test0", "real_name": "test00",
"email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_user_edit_change_password_successfully(self):
data = {"id": 1, "username": "test0", "real_name": "test00", "password": "111111",
"email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertIsNotNone(auth.authenticate(username="test0", password="111111"))
def test_error_admin_type(self):
response = self.client.get(self.url + "?admin_type=error")
self.assertEqual(response.data, {"code": 1, "data": u"参数错误"})
# 以下是用户分页的测试
def test_query_by_keyword(self):
user1 = User.objects.create(username="test1", real_name="aa")
user1.set_password("testaa")
@ -177,29 +212,18 @@ class UserAdminAPITest(APITestCase):
response = self.client.get(self.url + "?keyword=test1")
self.assertEqual(response.data["code"], 0)
def test_put_invalid_data(self):
data = {"username": "test", "password": "testaa", "email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_user_does_not_exist(self):
data = {"id": 2, "username": "test0", "real_name": "test00",
"password": "testaa","email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该用户不存在!"})
class UserInfoAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('user_info_api')
user = User.objects.create(username="test1", real_name="aa")
user.set_password("testaa")
user.save()
def test_success_user_edit_not_password(self):
data = {"id": 1, "username": "test0", "real_name": "test00",
"email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_success_user_edit_change_password(self):
data = {"id": 1, "username": "test0", "real_name": "test00", "password": "111111",
"email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertIsNotNone(auth.authenticate(username="test0", password="111111"))
def test_get_data_successfully(self):
self.client.login(username="test1", password="testaa")
self.assertEqual(self.client.get(self.url).data["code"], 0)
@login_required

View File

@ -9,7 +9,7 @@ class CreateAnnouncementSerializer(serializers.Serializer):
title = serializers.CharField(max_length=50)
content = serializers.CharField(max_length=10000)
is_global = serializers.BooleanField()
groups = serializers.ListField(child=serializers.IntegerField(), allow_empty=True)
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
class AnnouncementSerializer(serializers.ModelSerializer):
@ -31,4 +31,4 @@ class EditAnnouncementSerializer(serializers.Serializer):
content = serializers.CharField(max_length=10000)
visible = serializers.BooleanField()
is_global = serializers.BooleanField()
groups = serializers.ListField(child=serializers.IntegerField())
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])

View File

@ -5,6 +5,7 @@ from django.test import TestCase
from rest_framework.test import APITestCase, APIClient
from account.models import User
from group.models import Group
from announcement.models import Announcement
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
@ -13,76 +14,129 @@ class AnnouncementAdminAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse("announcement_admin_api")
user = User.objects.create(username="test", admin_type=SUPER_ADMIN)
user.set_password("testaa")
user.save()
user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
user1.set_password("testaa")
user1.save()
user2 = User.objects.create(username="test2", admin_type=ADMIN)
user2.set_password("testbb")
user2.save()
self.group = Group.objects.create(name="group1", description="des0",
join_group_setting=0, visible=True,
admin=user2)
self.announcement = Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test2"),
is_global=False)
# 以下是发布公告的测试
def test_invalid_format(self):
self.client.login(username="test", password="testaa")
self.client.login(username="test1", password="testaa")
data = {"title": "test1"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_success_announcement(self):
self.client.login(username="test", password="testaa")
data = {"title": "title0", "content": "content0"}
def test_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "content": "content0", "is_global": False}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"至少选择一个小组"})
def test_global_announcement_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "content": "content0", "is_global": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
def test_post_invalid_data(self):
self.client.login(username="test", password="testaa")
data = {"title": "test"}
def test_group_announcement_successfully(self):
self.client.login(username="test2", password="testbb")
data = {"title": "title0", "content": "content0", "is_global": False, "groups": [self.group.id]}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
def test_global_announcement_does_not_has_privileges(self):
self.client.login(username="test2", password="testbb")
data = {"title": "title0", "content": "content0", "is_global": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员可以创建全局公告"})
# 以下是编辑公告的测试
def test_put_invalid_data(self):
self.client.login(username="test", password="testaa")
self.client.login(username="test1", password="testaa")
data = {"title": "test0", "content": "test0", "visible": "True"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_announcement_does_not_exist(self):
self.client.login(username="test", password="testaa")
self.client.login(username="test1", password="testaa")
announcement = Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test"))
data = {"id": announcement.id + 1, "title": "11", "content": "22", "visible": True}
created_by=User.objects.get(username="test1"),
is_global=True)
data = {"id": announcement.id + 1, "title": "11", "content": "22",
"visible": True, "is_global": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该公告不存在!"})
self.assertEqual(response.data, {"code": 1, "data": u"公告不存在"})
def test_success_edit_announcement(self):
self.client.login(username="test", password="testaa")
announcement = Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test"))
data = {"id": announcement.id, "title": "11", "content": "22", "visible": True}
def test_edit_global_announcement_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.announcement.id, "title": "11", "content": "22",
"visible": True, "is_global": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_edit_group_announcement_successfully(self):
self.client.login(username="test2", password="testbb")
data = {"id": self.announcement.id, "title": "11", "content": "22",
"visible": True, "is_global": False, "groups": [self.group.id]}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "11")
self.assertEqual(response.data["data"]["content"], "22")
class AnnouncementAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse("announcement_list_api")
user = User.objects.create(username="test")
user.set_password("testaa")
user.save()
def test_edit_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.announcement.id, "title": "title0", "content": "content0",
"visible": True, "is_global": False}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"至少选择一个小组"})
def test_success_get_data(self):
# 以下是公告分页的测试
def test_get_data_successfully(self):
self.client.login(username="test1", password="testaa")
self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_keyword_announcement(self):
def test_keyword_global_announcement(self):
self.client.login(username="test1", password="testaa")
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test"),
visible=True)
created_by=User.objects.get(username="test1"),
visible=True,
is_global=True)
Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test"),
visible=False)
created_by=User.objects.get(username="test1"),
visible=False,
is_global=True)
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
for item in response.data["data"]:
self.assertEqual(item["visible"], True)
def test_keyword_group_announcement(self):
self.client.login(username="test2", password="testbb")
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test2"),
visible=True,
is_global=False)
Announcement.objects.create(title="cc",
content="CC",
created_by=User.objects.get(username="test2"),
visible=False,
is_global=False)
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
@ -98,12 +152,14 @@ class AnnouncementPageTest(TestCase):
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test"),
visible=True)
visible=True,
is_global=True)
Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test"),
visible=False)
visible=False,
is_global=True)
def test_visit_announcement_successfully(self):
response = self.client.get('/announcement/1/')
@ -112,3 +168,4 @@ class AnnouncementPageTest(TestCase):
def test_announcement_does_not_exist(self):
response = self.client.get('/announcement/3/')
self.assertTemplateUsed(response, "utils/error.html")

View File

@ -36,7 +36,7 @@ class AnnouncementAdminAPIView(APIView):
if request.user.admin_type == SUPER_ADMIN:
groups = Group.objects.filter(id__in=data["groups"])
else:
groups = Group.objects.filter(id__in=data["groups"], created_by=request.user)
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
if not groups.count():
return error_response(u"至少选择一个小组")
else:
@ -49,7 +49,6 @@ class AnnouncementAdminAPIView(APIView):
is_global=data["is_global"])
announcement.groups.add(*groups)
return success_response(u"公告发布成功!")
else:
return serializer_invalid_response(serializer)
@ -76,7 +75,7 @@ class AnnouncementAdminAPIView(APIView):
if request.user.admin_type == SUPER_ADMIN:
groups = Group.objects.filter(id__in=data["groups"])
else:
groups = Group.objects.filter(id__in=data["groups"], created_by=request.user)
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
if not groups.count():
return error_response(u"至少选择一个小组")
announcement.title = data["title"]

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('group', '0004_merge'),
]
operations = [
migrations.CreateModel(
name='Contest',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(unique=True, max_length=40)),
('description', models.TextField()),
('mode', models.IntegerField()),
('show_rank', models.BooleanField()),
('show_user_submission', models.BooleanField()),
('password', models.CharField(max_length=30, null=True, blank=True)),
('contest_type', models.IntegerField()),
('start_time', models.DateTimeField()),
('end_time', models.DateTimeField()),
('create_time', models.DateTimeField(auto_now_add=True)),
('last_updated_time', models.DateTimeField(auto_now=True)),
('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
('groups', models.ManyToManyField(to='group.Group')),
],
options={
'db_table': 'contest',
},
),
migrations.CreateModel(
name='ContestProblem',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(max_length=50)),
('description', models.TextField()),
('input_description', models.CharField(max_length=10000)),
('output_description', models.CharField(max_length=10000)),
('samples', models.TextField(blank=True)),
('test_case_id', models.CharField(max_length=40)),
('hint', models.TextField(null=True, blank=True)),
('create_time', models.DateTimeField(auto_now_add=True)),
('time_limit', models.IntegerField()),
('memory_limit', models.IntegerField()),
('visible', models.BooleanField(default=True)),
('total_submit_number', models.IntegerField(default=0)),
('total_accepted_number', models.IntegerField(default=0)),
('sort_index', models.CharField(max_length=30)),
('contest', models.ForeignKey(to='contest.Contest')),
('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
],
options={
'db_table': 'contest_problem',
},
),
migrations.CreateModel(
name='ContestProblemTestCase',
fields=[
('id', models.CharField(max_length=40, serialize=False, primary_key=True, db_index=True)),
('score', models.IntegerField()),
('problem', models.ForeignKey(to='contest.ContestProblem')),
],
options={
'db_table': 'contest_problem_test_case',
},
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('contest', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='contest',
name='visible',
field=models.BooleanField(default=True),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('contest', '0002_contest_visible'),
]
operations = [
migrations.AddField(
model_name='contestproblem',
name='difficulty',
field=models.IntegerField(default=1),
preserve_default=False,
),
]

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('contest', '0003_contestproblem_difficulty'),
]
operations = [
migrations.RemoveField(
model_name='contestproblem',
name='difficulty',
),
]

View File

@ -3,18 +3,25 @@ from django.db import models
from account.models import User
from problem.models import AbstractProblem
from group.models import Group
class Contest(models.Model):
title = models.CharField(max_length=40)
title = models.CharField(max_length=40, unique=True)
description = models.TextField()
# 比赛模式 现在有 acm 模式,按照 ac 题目数量得分模式,
# 按照 ac 的题目的总分得分模式和按照通过的测试用例总分得分模式等
# 比赛模式0 即为是acm模式1 即为是按照总的 ac 题目数量排名模式2 即为按照 ac 的题目的总分排名模式
mode = models.IntegerField()
# 是否显示排名结果
show_rank = models.BooleanField()
# 如果这一项不为空,那这就不是公开赛,需要密码才能进入
# 是否显示别人的提交记录
show_user_submission = models.BooleanField()
# 只能超级管理员创建公开赛,管理员只能创建小组内部的比赛
# 如果这一项不为空,即为有密码的公开赛,没有密码的可以为小组赛或者是公开赛(此时用比赛的类型来表示)
password = models.CharField(max_length=30, blank=True, null=True)
# 比赛的类型: 0 即为是小组赛1 即为是无密码的公开赛2 即为是有密码的公开赛
contest_type = models.IntegerField()
# 开始时间
start_time = models.DateTimeField()
# 结束时间
@ -23,7 +30,11 @@ class Contest(models.Model):
create_time = models.DateTimeField(auto_now_add=True)
# 最后修改时间
last_updated_time = models.DateTimeField(auto_now=True)
# 这个比赛是谁创建的
created_by = models.ForeignKey(User)
groups = models.ManyToManyField(Group)
# 是否可见 false的话相当于删除
visible = models.BooleanField(default=True)
class Meta:
db_table = "contest"

105
contest/serializers.py Normal file
View File

@ -0,0 +1,105 @@
# coding=utf-8
import json
from rest_framework import serializers
from account.models import User
from account.serializers import UserSerializer
from .models import Contest, ContestProblem
class CreateContestSerializer(serializers.Serializer):
title = serializers.CharField(max_length=40)
description = serializers.CharField(max_length=5000)
mode = serializers.IntegerField()
contest_type = serializers.IntegerField()
show_rank = serializers.BooleanField()
show_user_submission = serializers.BooleanField()
password = serializers.CharField(max_length=30, required=False, default=None)
start_time = serializers.DateTimeField()
end_time = serializers.DateTimeField()
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
visible = serializers.BooleanField()
class ContestSerializer(serializers.ModelSerializer):
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["username"]
created_by = UserSerializer()
class Meta:
model = Contest
class EditContestSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField(max_length=40)
description = serializers.CharField(max_length=10000)
mode = serializers.IntegerField()
contest_type = serializers.IntegerField()
show_rank = serializers.BooleanField()
show_user_submission = serializers.BooleanField()
password = serializers.CharField(max_length=30, required=False, default=None)
start_time = serializers.DateTimeField()
end_time = serializers.DateTimeField()
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
visible = serializers.BooleanField()
class ContestProblemSampleSerializer(serializers.ListField):
input = serializers.CharField(max_length=3000)
output = serializers.CharField(max_length=3000)
class JSONField(serializers.Field):
def to_representation(self, value):
return json.loads(value)
class CreateContestProblemSerializer(serializers.Serializer):
contest_id = serializers.IntegerField()
title = serializers.CharField(max_length=50)
description = serializers.CharField(max_length=10000)
input_description = serializers.CharField(max_length=10000)
output_description = serializers.CharField(max_length=10000)
# [{"input": "1 1", "output": "2"}]
samples = ContestProblemSampleSerializer()
test_case_id = serializers.CharField(max_length=40)
time_limit = serializers.IntegerField()
memory_limit = serializers.IntegerField()
hint = serializers.CharField(max_length=3000, allow_blank=True)
sort_index = serializers.CharField(max_length=30)
class ContestProblemSerializer(serializers.ModelSerializer):
class ContestSerializer(serializers.ModelSerializer):
class Meta:
model = Contest
fields = ["title", "id"]
samples = JSONField()
contest = ContestSerializer()
created_by = UserSerializer()
class Meta:
model = ContestProblem
class EditContestProblemSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField(max_length=50)
description = serializers.CharField(max_length=10000)
input_description = serializers.CharField(max_length=10000)
output_description = serializers.CharField(max_length=10000)
test_case_id = serializers.CharField(max_length=40)
time_limit = serializers.IntegerField()
memory_limit = serializers.IntegerField()
samples = ContestProblemSampleSerializer()
hint = serializers.CharField(max_length=3000, allow_blank=True)
visible = serializers.BooleanField()
sort_index = serializers.CharField(max_length=30)

View File

@ -1,3 +1,336 @@
# coding=utf-8
import json
from django.core.urlresolvers import reverse
from django.test import TestCase
# Create your tests here.
from rest_framework.test import APITestCase, APIClient
from account.models import User
from group.models import Group
from contest.models import Contest, ContestProblem
from announcement.models import Announcement
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
class ContestAdminAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('contest_admin_api')
user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
user1.set_password("testaa")
user1.save()
user2 = User.objects.create(username="test2", admin_type=ADMIN)
user2.set_password("testbb")
user2.save()
user3 = User.objects.create(username="test3", admin_type=REGULAR_USER)
user3.set_password("testcc")
user3.save()
self.group = Group.objects.create(name="group1", description="des0",
join_group_setting=0, visible=True,
admin=user2)
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.group_contest = Contest.objects.create(title="titley", description="descriptiony", 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="test1", password="testaa")
data = {"title": "test1"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_global_contest_does_not_has_privileges(self):
self.client.login(username="test2", password="testbb")
data = {"title": "title0", "description": "description0", "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": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员才可创建公开赛"})
def test_global_contest_password_exists(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "description": "description0", "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", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"此比赛为有密码的公开赛,密码不可为空"})
def test_group_contest_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "description": "description0", "mode": 1, "contest_type": 0,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"请至少选择一个小组"})
def test_global_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title1", "description": "description1", "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": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_group_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title3", "description": "description3", "mode": 1, "contest_type": 0,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "groups": [self.group.id], "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_time_error(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title2", "description": "description2", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T12:00:00.000Z",
"end_time": "2015-08-15T10:00:00.000Z", "password": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛的开始时间不能晚于或等于比赛结束的时间"})
def test_contest_has_exists(self):
self.client.login(username="test1", password="testaa")
data = {"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": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛名已经存在"})
# 以下是编辑比赛的测试
def test_put_invalid_data(self):
self.client.login(username="test1", password="testaa")
data = {"title": "test0", "description": "description0"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_contest_does_not_exist(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id + 10, "title": "title2", "description": "description2", "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": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该比赛不存在!"})
def test_edit_global_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "titlez", "description": "descriptionz", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T13:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "titlez")
self.assertEqual(response.data["data"]["end_time"], "2015-08-15T13:00:00Z")
def test_edit_group_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.group_contest.id, "title": "titleyyy", "description": "descriptionyyyy", "mode": 1,
"contest_type": 0, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T13:00:00.000Z",
"groups": [self.group.id], "visible": False}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "titleyyy")
self.assertEqual(response.data["data"]["end_time"], "2015-08-15T13:00:00Z")
self.assertEqual(response.data["data"]["visible"], False)
def test_edit_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.group_contest.id, "title": "titleyyy", "description": "descriptionyyyy", "mode": 1,
"contest_type": 0, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T13:00:00.000Z", "visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"请至少选择一个小组"})
def test_edit_contest_has_exists(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "titley", "description": "descriptiony", "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": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该比赛名称已经存在"})
def test_edit_global_contest_does_not_has_privileges(self):
self.client.login(username="test2", password="testbb")
data = {"id": self.global_contest.id, "title": "titlexxxxxxxxx", "description": "descriptionxxxxxx", "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": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员才可创建公开赛"})
def test_edit_global_contest_password_exists(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "title0", "description": "description0", "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", "visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"此比赛为有密码的公开赛,密码不可为空"})
def test_edit_time_error(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "titleaaaa", "description": "descriptionaaaaa", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T12:00:00.000Z", "end_time": "2015-08-15T10:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛的开始时间不能晚于或等于比赛结束的时间"})
# 以下是比赛分页的测试
def test_get_data_successfully(self):
self.client.login(username="test1", password="testaa")
self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_keyword_contest(self):
self.client.login(username="test1", password="testaa")
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
for item in response.data["data"]:
self.assertEqual(item["visible"], True)
def test_query_by_keyword(self):
self.client.login(username="test1", password="testaa")
response = self.client.get(self.url + "?keyword=title1")
self.assertEqual(response.data["code"], 0)
class ContestProblemAdminAPItEST(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('contest_problem_admin_api')
self.user = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
self.user.set_password("testaa")
self.user.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_invalid_format(self):
data = {"title": "test1"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_release_contest_problem_successfully(self):
data = {"title": "title2",
"description": "description2",
"input_description": "input_description2",
"output_description": "output_description2",
"test_case_id": "1",
"source": "source1",
"samples": [{"input": "1 1", "output": "2"}],
"time_limit": "100",
"memory_limit": "1000",
"hint": "hint1",
"sort_index": "b",
"contest_id": self.global_contest.id}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_contest_does_not_exists(self):
data = {"title": "titlezzzzzzzz",
"description": "descriptionzzzzzzzzzzz",
"input_description": "input_description2",
"output_description": "output_description2",
"test_case_id": "1",
"source": "source1",
"samples": [{"input": "1 1", "output": "2"}],
"time_limit": "100",
"memory_limit": "1000",
"hint": "hint1",
"sort_index": "b",
"contest_id": self.global_contest.id + 10}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛不存在"})
# 以下是编辑比赛题目的测试
def test_invalid_data(self):
data = {"title": "test1"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_edit_problem_does_not_exist(self):
data = {"id": self.contest_problem.id + 1,
"title": "title2",
"description": "description2",
"input_description": "input_description2",
"output_description": "output_description2",
"test_case_id": "1",
"source": "source1",
"samples": [{"input": "1 1", "output": "2"}],
"time_limit": "100",
"memory_limit": "1000",
"hint": "hint1",
"sort_index": "b",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该比赛题目不存在!"})
def test_edit_problem_successfully(self):
data = {"id": self.contest_problem.id,
"title": "title2222222",
"description": "description22222222",
"input_description": "input_description2",
"output_description": "output_description2",
"test_case_id": "1",
"source": "source1",
"samples": [{"input": "1 1", "output": "2"}],
"time_limit": "100",
"memory_limit": "1000",
"hint": "hint1",
"sort_index": "b",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
# 以下是比赛题目分页的测试
def test_get_data_successfully(self):
self.client.login(username="test1", password="testaa")
self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_keyword_contest(self):
self.client.login(username="test1", password="testaa")
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
for item in response.data["data"]:
self.assertEqual(item["visible"], True)
def test_query_by_keyword(self):
self.client.login(username="test1", password="testaa")
response = self.client.get(self.url + "?keyword=title1")
self.assertEqual(response.data["code"], 0)
def test_query_contest_problem_does_not_exist(self):
data = {"contest_problem_id": 1000000}
response = self.client.get(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛题目不存在"})
def test_query_contest_problem_exists(self):
data = {"contest_problem_id": self.contest_problem.id}
response = self.client.get(self.url, data=data)
self.assertEqual(response.data["code"], 0)

View File

@ -1,3 +1,223 @@
# coding=utf-8
import json
from django.shortcuts import render
from django.db import IntegrityError
from django.utils import dateparse
from django.db.models import Q
from rest_framework.views import APIView
from utils.shortcuts import (serializer_invalid_response, error_response,
success_response, paginate, rand_str, error_page)
# Create your views here.
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
from group.models import Group
from .models import Contest, ContestProblem
from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer,
CreateContestProblemSerializer, ContestProblemSerializer, EditContestProblemSerializer)
def contest_page(request, contest_id):
pass
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
groups = []
# 首先判断比赛的类型: 0 即为是小组赛1 即为是无密码的公开赛2 即为是有密码的公开赛
# 此时为有密码的公开赛,并且此时只能超级管理员才有权限此创建比赛
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"请至少选择一个小组")
if data["start_time"] >= data["end_time"]:
return error_response(u"比赛的开始时间不能晚于或等于比赛结束的时间")
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"],
show_user_submission=data["show_user_submission"],
start_time=dateparse.parse_datetime(data["start_time"]),
end_time=dateparse.parse_datetime(data["end_time"]),
created_by=request.user, visible=data["visible"])
except IntegrityError:
return error_response(u"比赛名已经存在")
contest.groups.add(*groups)
return success_response(ContestSerializer(contest).data)
else:
return serializer_invalid_response(serializer)
def put(self, request):
"""
比赛编辑json api接口
---
request_serializer: EditContestSerializer
response_serializer: ContestSerializer
"""
serializer = EditContestSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
groups = []
try:
contest = Contest.objects.get(id=data["id"])
except Contest.DoesNotExist:
return error_response(u"该比赛不存在!")
try:
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"请至少选择一个小组")
if data["start_time"] >= data["end_time"]:
return error_response(u"比赛的开始时间不能晚于或等于比赛结束的时间")
contest.title = data["title"]
contest.description = data["description"]
contest.mode = data["mode"]
contest.contest_type = data["contest_type"]
contest.show_rank = data["show_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"])
contest.visible = data["visible"]
contest.password = data["password"]
contest.save()
contest.groups.clear()
contest.groups.add(*groups)
return success_response(ContestSerializer(contest).data)
else:
return serializer_invalid_response(serializer)
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
try:
contest = Contest.objects.get(id=data["contest_id"])
except Contest.DoesNotExist:
return error_response(u"比赛不存在")
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"],
contest=contest,
sort_index=data["sort_index"])
return success_response(ContestProblemSerializer(contest_problem).data)
else:
return serializer_invalid_response(serializer)
def put(self, request):
"""
比赛题目编辑json api接口
---
request_serializer: EditContestProblemSerializer
response_serializer: ContestProblemSerializer
"""
serializer = EditContestProblemSerializer(data=request.data)
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()
return success_response(ContestProblemSerializer(contest_problem).data)
else:
return serializer_invalid_response(serializer)
def get(self, request):
"""
比赛题目分页json api接口
---
response_serializer: ProblemSerializer
"""
contest_problem_id = request.GET.get("contest_problem_id", None)
if contest_problem_id:
try:
contest_problem = ContestProblem.objects.get(id=contest_problem_id)
return success_response(ContestProblemSerializer(contest_problem).data)
except ContestProblem.DoesNotExist:
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))
return paginate(request, contest_problem, ContestProblemSerializer)

View File

@ -226,7 +226,8 @@ class JoinGroupRequestAdminAPIView(APIView, GroupAPIViewBase):
if serializer.is_valid():
data = serializer.data
try:
join_request = JoinGroupRequest.objects.get(id=data["request_id"], group__admin=request.user, status=False)
join_request = JoinGroupRequest.objects.get(id=data["request_id"], group__admin=request.user,
status=False)
except JoinGroupRequest.DoesNotExist:
return error_response(u"请求不存在")

View File

@ -52,6 +52,7 @@ INSTALLED_APPS = (
'problem',
'admin',
'submission',
'contest',
'rest_framework',
'rest_framework_swagger',
@ -156,3 +157,8 @@ LOGGING = {
}
},
}
REST_FRAMEWORK = {
'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}

View File

@ -8,6 +8,8 @@ from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterA
UserAdminAPIView, UserInfoAPIView)
from announcement.views import AnnouncementAdminAPIView
from contest.views import ContestAdminAPIView, ContestProblemAdminAPIView
from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView,
JoinGroupAPIView, JoinGroupRequestAdminAPIView)
@ -35,6 +37,7 @@ urlpatterns = [
url(r'^api/username_check/$', UsernameCheckAPIView.as_view(), name="username_check_api"),
url(r'^api/email_check/$', EmailCheckAPIView.as_view(), name="email_check_api"),
url(r'^api/admin/announcement/$', AnnouncementAdminAPIView.as_view(), name="announcement_admin_api"),
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'^announcement/(?P<announcement_id>\d+)/$', "announcement.views.announcement_page",
@ -49,6 +52,7 @@ urlpatterns = [
url(r'^api/admin/group_member/$', GroupMemberAdminAPIView.as_view(), name="group_member_admin_api"),
url(r'^api/admin/group_join/$', JoinGroupAPIView.as_view(), name="group_join_admin_api"),
url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"),
url(r'^api/admin/contest_problem/$', ContestProblemAdminAPIView.as_view(), name="contest_problem_admin_api"),
url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"),
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",

View File

@ -32,8 +32,6 @@ class AbstractProblem(models.Model):
# last_update_time = models.DateTimeField(auto_now=True)
# 这个题是谁创建的
created_by = models.ForeignKey(User)
# 来源
source = models.CharField(max_length=30, blank=True, null=True)
# 时间限制 单位是毫秒
time_limit = models.IntegerField()
# 内存限制 单位是MB
@ -54,3 +52,5 @@ class Problem(AbstractProblem):
difficulty = models.IntegerField()
# 标签
tags = models.ManyToManyField(ProblemTag)
# 来源
source = models.CharField(max_length=30, blank=True, null=True)

View File

@ -1,7 +1,7 @@
# coding=utf-8
import json
from django.test import TestCase
from django.test import TestCase, Client
from django.core.urlresolvers import reverse
from rest_framework.test import APITestCase, APIClient
@ -39,7 +39,6 @@ class ProblemPageTest(TestCase):
self.assertTemplateUsed(response, "utils/error.html")
class ProblemAdminTest(APITestCase):
def _create_data(self, problem_id, visible, tags):
data = {"id": problem_id,
@ -164,3 +163,29 @@ class ProblemTagAdminAPITest(APITestCase):
def test_get_all_problem_tag_successfully(self):
self.assertEqual(self.client.get(self.url).data["code"], 0)
class ProblemListPageTest(TestCase):
def setUp(self):
self.client = Client()
self.url = reverse('problem_list_page', kwargs={"page": 1})
self.user = User.objects.create(username="test", admin_type=SUPER_ADMIN)
self.user.set_password("testaa")
self.user.save()
self.client.login(username="test", password="testaa")
ProblemTag.objects.create(name="tag1")
ProblemTag.objects.create(name="tag2")
self.problem = Problem.objects.create(title="title1",
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=User.objects.get(username="test"))

View File

@ -57,7 +57,6 @@ class ProblemAdminAPIView(APIView):
difficulty=data["difficulty"],
created_by=request.user,
hint=data["hint"])
for tag in data["tags"]:
try:
tag = ProblemTag.objects.get(name=tag)

View File

@ -69,6 +69,22 @@ li.list-group-item {
padding: 0 0;
}
.ac-flag{
.ac-flag {
color: green;
}
.CodeMirror{
min-height: 250px;
_height:250px;
height: auto;
}
.CodeMirror-scroll {
overflow: auto;
min-height: 250px;
_height:250px;
height: auto;
position: relative;
outline: none;
}

View File

@ -4,7 +4,7 @@
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation" class="active">
<a href="problem.html">题目</a></li>
<a href="/problem/{{ problem.id }}/">题目</a></li>
<li role="presentation"><a href="/problem/{{ problem.id }}/my_submissions/">我的提交</a></li>
</ul>
{% include "oj/problem/_problem_header.html" %}