From d64b99eed3d559ad0fa7349e9c6ec2f64c4ffb0d Mon Sep 17 00:00:00 2001 From: hohoTT <609029365@qq.com> Date: Fri, 7 Aug 2015 20:25:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E7=94=A8visible?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E5=85=AC=E5=91=8A=E7=9A=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=A2=9E=E5=8A=A0=E4=BA=86=E7=9B=B8=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- announcement/tests.py | 19 +++++++++++++++++++ announcement/views.py | 5 ++++- oj/urls.py | 4 +++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/announcement/tests.py b/announcement/tests.py index a7fd1208..fb27fe56 100644 --- a/announcement/tests.py +++ b/announcement/tests.py @@ -62,6 +62,25 @@ class AnnouncementAPITest(APITestCase): def setUp(self): self.client = APIClient() self.url = reverse("announcement_list_api") + user = User.objects.create(username="test") + user.set_password("test") + user.save() def test_success_get_data(self): 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) diff --git a/announcement/views.py b/announcement/views.py index bc148893..a96b1f1d 100644 --- a/announcement/views.py +++ b/announcement/views.py @@ -57,5 +57,8 @@ class AnnouncementAPIView(APIView): --- 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) diff --git a/oj/urls.py b/oj/urls.py index 97ecb024..a69c8ee7 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -4,7 +4,7 @@ from django.contrib import admin from django.views.generic import TemplateView from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, \ - EmailCheckAPIView + EmailCheckAPIView, UserAPIView, UserAdminAPIView from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView 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/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/user/$', UserAdminAPIView.as_view(), name="user_admin_api"), url(r'^problem/(?P\d+)/$', "problem.views.problem_page", name="problem_page"), 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'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"), From 69385e96d213b5c5d2e8a077ce665da811e57041 Mon Sep 17 00:00:00 2001 From: hohoTT <609029365@qq.com> Date: Fri, 7 Aug 2015 20:25:58 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=AE=A1=E7=90=86=E5=92=8C=E7=BC=96=E8=BE=91=E7=9A=84?= =?UTF-8?q?API=E5=8F=8A=E7=9B=B8=E5=BA=94=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/migrations/0001_initial.py | 14 ++++---- account/models.py | 2 ++ account/serializers.py | 17 +++++++++ account/tests.py | 56 ++++++++++++++++++++++++++++++ account/views.py | 55 +++++++++++++++++++++++++++-- 5 files changed, 136 insertions(+), 8 deletions(-) diff --git a/account/migrations/0001_initial.py b/account/migrations/0001_initial.py index 4f552993..03d55846 100644 --- a/account/migrations/0001_initial.py +++ b/account/migrations/0001_initial.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.db import models, migrations -import django.db.models.deletion +import account.models class Migration(migrations.Migration): @@ -18,10 +18,17 @@ class Migration(migrations.Migration): ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)), ('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={ 'db_table': 'user', }, + managers=[ + ('objects', account.models.UserManager()), + ], ), migrations.CreateModel( name='AdminGroup', @@ -29,9 +36,4 @@ class Migration(migrations.Migration): ('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), - ), ] diff --git a/account/models.py b/account/models.py index 7c5afb96..a724f5a7 100644 --- a/account/models.py +++ b/account/models.py @@ -21,6 +21,8 @@ class User(AbstractBaseUser): real_name = models.CharField(max_length=30, 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是超级管理员 admin_type = models.IntegerField(default=0) diff --git a/account/serializers.py b/account/serializers.py index 209e4905..d82b36db 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -1,6 +1,8 @@ # coding=utf-8 from rest_framework import serializers +from .models import User + class UserLoginSerializer(serializers.Serializer): username = serializers.CharField(max_length=30) @@ -27,3 +29,18 @@ class UserChangePasswordSerializer(serializers.Serializer): old_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) diff --git a/account/tests.py b/account/tests.py index 3529bb6e..41158294 100644 --- a/account/tests.py +++ b/account/tests.py @@ -144,6 +144,62 @@ class UserChangePasswordAPITest(APITestCase): 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 def login_required_FBV_test_without_args(request): return HttpResponse("function based view test1") diff --git a/account/views.py b/account/views.py index 7214c8a9..ec29f970 100644 --- a/account/views.py +++ b/account/views.py @@ -1,13 +1,15 @@ # coding=utf-8 from django.contrib import auth from django.shortcuts import render +from django.db.models import Q + 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 .serializers import UserLoginSerializer, UsernameCheckSerializer, UserRegisterSerializer, \ - UserChangePasswordSerializer, EmailCheckSerializer + UserChangePasswordSerializer, EmailCheckSerializer, UserSerializer, EditUserSerializer class UserLoginAPIView(APIView): @@ -114,3 +116,52 @@ class EmailCheckAPIView(APIView): return success_response(False) else: 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)