Accept Merge Request #43 : (hohoTT-dev -> dev)

Merge Request: 增加了用户管理和编辑的API及相应的测试
Created By: @hohoTT
Accepted By: @hohoTT
URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/43
This commit is contained in:
hohoTT 2015-08-07 20:32:06 +08:00
commit 31479283ce
8 changed files with 162 additions and 10 deletions

View File

@ -2,7 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
import django.db.models.deletion import account.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -18,10 +18,17 @@ class Migration(migrations.Migration):
('password', models.CharField(max_length=128, verbose_name='password')), ('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)), ('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)),
('username', models.CharField(unique=True, max_length=30)), ('username', models.CharField(unique=True, max_length=30)),
('real_name', models.CharField(max_length=30, null=True, blank=True)),
('email', models.EmailField(max_length=254, null=True, blank=True)),
('create_time', models.DateTimeField(auto_now_add=True)),
('admin_type', models.IntegerField(default=0)),
], ],
options={ options={
'db_table': 'user', 'db_table': 'user',
}, },
managers=[
('objects', account.models.UserManager()),
],
), ),
migrations.CreateModel( migrations.CreateModel(
name='AdminGroup', name='AdminGroup',
@ -29,9 +36,4 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
], ],
), ),
migrations.AddField(
model_name='user',
name='admin_group',
field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='account.AdminGroup', null=True),
),
] ]

View File

@ -21,6 +21,8 @@ class User(AbstractBaseUser):
real_name = models.CharField(max_length=30, blank=True, null=True) real_name = models.CharField(max_length=30, blank=True, null=True)
# 用户邮箱 # 用户邮箱
email = models.EmailField(max_length=254, blank=True, null=True) email = models.EmailField(max_length=254, blank=True, null=True)
# 用户注册时间
create_time = models.DateTimeField(auto_now_add=True)
# 0代表不是管理员 1是普通管理员 2是超级管理员 # 0代表不是管理员 1是普通管理员 2是超级管理员
admin_type = models.IntegerField(default=0) admin_type = models.IntegerField(default=0)

View File

@ -1,6 +1,8 @@
# coding=utf-8 # coding=utf-8
from rest_framework import serializers from rest_framework import serializers
from .models import User
class UserLoginSerializer(serializers.Serializer): class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField(max_length=30) username = serializers.CharField(max_length=30)
@ -27,3 +29,18 @@ class UserChangePasswordSerializer(serializers.Serializer):
old_password = serializers.CharField(max_length=30, min_length=6) old_password = serializers.CharField(max_length=30, min_length=6)
new_password = serializers.CharField(max_length=30, min_length=6) new_password = serializers.CharField(max_length=30, min_length=6)
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
exclude = ["password"]
class EditUserSerializer(serializers.Serializer):
id = serializers.IntegerField()
username = serializers.CharField(max_length=30)
real_name = serializers.CharField(max_length=30)
password = serializers.CharField(max_length=30, min_length=6, required=True)
email = serializers.EmailField(max_length=254)
admin_type = serializers.IntegerField(default=0)

View File

@ -144,6 +144,62 @@ class UserChangePasswordAPITest(APITestCase):
self.assertEqual(response.data, {"code": 0, "data": u"用户密码修改成功!"}) self.assertEqual(response.data, {"code": 0, "data": u"用户密码修改成功!"})
class UserAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse("user_list_api")
def test_success_get_data(self):
self.assertEqual(self.client.get(self.url).data["code"], 0)
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")
user1.save()
user2 = User.objects.create(username="test2", real_name="bb")
user2.set_password("testbb")
user2.save()
user3 = User.objects.create(username="test3", real_name="cc")
user3.set_password("testcc")
user3.save()
response = self.client.get(self.url + "?keyword=test1")
self.assertEqual(response.data["code"], 0)
class UserAdminAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse("user_admin_api")
user = User.objects.create(username="test")
user.set_password("testaa")
user.save()
def test_put_invalid_data(self):
self.client.login(username="test", password="test")
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"该用户不存在!"})
def test_success_user_edit_not_password(self):
data = {"id": 1, "username": "test0", "real_name": "test00", "password": "aaaaaa",
"email": "60@qq.com", "admin_type": "2"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
@login_required @login_required
def login_required_FBV_test_without_args(request): def login_required_FBV_test_without_args(request):
return HttpResponse("function based view test1") return HttpResponse("function based view test1")

View File

@ -1,13 +1,15 @@
# coding=utf-8 # coding=utf-8
from django.contrib import auth from django.contrib import auth
from django.shortcuts import render from django.shortcuts import render
from django.db.models import Q
from rest_framework.views import APIView from rest_framework.views import APIView
from utils.shortcuts import serializer_invalid_response, error_response, success_response from utils.shortcuts import serializer_invalid_response, error_response, success_response, paginate
from .models import User from .models import User
from .serializers import UserLoginSerializer, UsernameCheckSerializer, UserRegisterSerializer, \ from .serializers import UserLoginSerializer, UsernameCheckSerializer, UserRegisterSerializer, \
UserChangePasswordSerializer, EmailCheckSerializer UserChangePasswordSerializer, EmailCheckSerializer, UserSerializer, EditUserSerializer
class UserLoginAPIView(APIView): class UserLoginAPIView(APIView):
@ -114,3 +116,52 @@ class EmailCheckAPIView(APIView):
return success_response(False) return success_response(False)
else: else:
return serializer_invalid_response(serializer) return serializer_invalid_response(serializer)
class UserAPIView(APIView):
def get(self, request):
"""
用户分页json api接口
---
response_serializer: UserSerializer
"""
user = User.objects.all().order_by("-create_time")
admin_type = request.GET.get("admin_type", None)
if admin_type:
try:
user = user.filter(admin_type=int(admin_type))
except ValueError:
return error_response(u"参数错误")
keyword = request.GET.get("keyword", None)
if keyword:
user = user.filter(Q(username__contains=keyword) |
Q(real_name__contains=keyword) |
Q(email__contains=keyword))
return paginate(request, user, UserSerializer)
class UserAdminAPIView(APIView):
def put(self, request):
"""
用户编辑json api接口
---
request_serializer: EditUserSerializer
response_serializer: UserSerializer
"""
serializer = EditUserSerializer(data=request.DATA)
if serializer.is_valid():
data = serializer.data
try:
user = User.objects.get(id=data["id"])
except User.DoesNotExist:
return error_response(u"该用户不存在!")
user.username = data["username"]
user.real_name = data["real_name"]
user.email = data["email"]
user.admin_type = data["admin_type"]
if data["password"]:
user.set_password(data["password"])
user.save()
return success_response(UserSerializer(user).data)
else:
return serializer_invalid_response(serializer)

View File

@ -62,6 +62,25 @@ class AnnouncementAPITest(APITestCase):
def setUp(self): def setUp(self):
self.client = APIClient() self.client = APIClient()
self.url = reverse("announcement_list_api") self.url = reverse("announcement_list_api")
user = User.objects.create(username="test")
user.set_password("test")
user.save()
def test_success_get_data(self): def test_success_get_data(self):
self.assertEqual(self.client.get(self.url).data["code"], 0) self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_keyword_announcement(self):
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test"),
visible=True)
Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test"),
visible=False)
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)

View File

@ -57,5 +57,8 @@ class AnnouncementAPIView(APIView):
--- ---
response_serializer: AnnouncementSerializer response_serializer: AnnouncementSerializer
""" """
announcement = Announcement.objects.all().order_by("last_update_time") announcement = Announcement.objects.all().order_by("-last_update_time")
visible = request.GET.get("visible", None)
if visible:
announcement = announcement.filter(visible=(visible == "true"))
return paginate(request, announcement, AnnouncementSerializer) return paginate(request, announcement, AnnouncementSerializer)

View File

@ -4,7 +4,7 @@ from django.contrib import admin
from django.views.generic import TemplateView from django.views.generic import TemplateView
from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, \ from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, \
EmailCheckAPIView EmailCheckAPIView, UserAPIView, UserAdminAPIView
from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView
from admin.views import AdminTemplateView from admin.views import AdminTemplateView
@ -21,9 +21,11 @@ urlpatterns = [
url(r'^api/username_check/$', UsernameCheckAPIView.as_view(), name="username_check_api"), 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/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/announcement/$', AnnouncementAdminAPIView.as_view(), name="announcement_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'^api/announcements/$', AnnouncementAPIView.as_view(), name="announcement_list_api"), url(r'^api/announcements/$', AnnouncementAPIView.as_view(), name="announcement_list_api"),
url(r'^api/users/$', UserAPIView.as_view(), name="user_list_api"),
url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"), url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"),
url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"), url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"),