Accept Merge Request #58 : (sxw-dev -> dev)

Merge Request: 增加小组功能
Created By: @hohoTT
Accepted By: @hohoTT
URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/58
This commit is contained in:
hohoTT
2015-08-09 13:01:44 +08:00
12 changed files with 210 additions and 3 deletions

View File

@@ -14,6 +14,11 @@ class UserManager(models.Manager):
return self.get(**{self.model.USERNAME_FIELD: username})
REGULAR_USER = 0
ADMIN = 1
SUPER_ADMIN = 2
class User(AbstractBaseUser):
# 用户名
username = models.CharField(max_length=30, unique=True)

16
admin/middleware.py Normal file
View File

@@ -0,0 +1,16 @@
# coding=utf-8
import json
from django.http import HttpResponse, HttpResponseRedirect
class AdminRequiredMiddleware(object):
def process_request(self, request):
path = request.path_info
if path.startswith("/admin/") or path.startswith("/api/admin/"):
if not request.user.is_authenticated():
if request.is_ajax():
return HttpResponse(json.dumps({"code": 1, "data": u"请先登录"}),
content_type="application/json")
else:
return HttpResponseRedirect("/login/")

0
group/__init__.py Normal file
View File

3
group/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@@ -0,0 +1,45 @@
# -*- 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),
]
operations = [
migrations.CreateModel(
name='Group',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=30)),
('description', models.TextField()),
('create_time', models.DateTimeField(auto_now_add=True)),
('join_group_setting', models.IntegerField()),
('visible', models.BooleanField(default=True)),
('admin', models.ForeignKey(related_name='my_groups', to=settings.AUTH_USER_MODEL)),
('members', models.ManyToManyField(to=settings.AUTH_USER_MODEL)),
],
options={
'db_table': 'group',
},
),
migrations.CreateModel(
name='JoinGroupRequest',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('message', models.TextField()),
('create_time', models.DateTimeField(auto_now_add=True)),
('status', models.BooleanField(default=False)),
('group', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(related_name='my_join_group_requests', to=settings.AUTH_USER_MODEL)),
],
options={
'db_table': 'join_group_request',
},
),
]

View File

31
group/models.py Normal file
View File

@@ -0,0 +1,31 @@
# coding=utf-8
from django.db import models
from account.models import User
class Group(models.Model):
name = models.CharField(max_length=30)
description = models.TextField()
create_time = models.DateTimeField(auto_now_add=True)
admin = models.ForeignKey(User, related_name="my_groups")
# 0是公开 1是需要申请后加入 2是不允许任何人加入
join_group_setting = models.IntegerField()
members = models.ManyToManyField(User)
# 解散小组后这一项改为False
visible = models.BooleanField(default=True)
class Meta:
db_table = "group"
class JoinGroupRequest(models.Model):
group = models.ForeignKey(User)
user = models.ForeignKey(User, related_name="my_join_group_requests")
message = models.TextField()
create_time = models.DateTimeField(auto_now_add=True)
# 是否处理
status = models.BooleanField(default=False)
class Meta:
db_table = "join_group_request"

27
group/serializers.py Normal file
View File

@@ -0,0 +1,27 @@
# coding=utf-8
from rest_framework import serializers
from .models import Group
class CreateGroupSerializer(serializers.Serializer):
name = serializers.CharField(max_length=20)
description = serializers.CharField(max_length=300)
join_group_setting = serializers.IntegerField(min_value=0, max_value=2)
class EditGroupSerializer(serializers.Serializer):
name = serializers.CharField(max_length=20)
description = serializers.CharField(max_length=300)
join_group_setting = serializers.IntegerField()
class JoinGroupRequestSerializer(serializers.Serializer):
group = serializers.IntegerField()
message = serializers.CharField(max_length=30)
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
exclude = ["members"]

3
group/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

72
group/views.py Normal file
View File

@@ -0,0 +1,72 @@
# coding=utf-8
from django.shortcuts import render
from rest_framework.views import APIView
from utils.shortcuts import error_response, serializer_invalid_response, success_response, paginate
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
from .models import Group, JoinGroupRequest
from .serializers import (CreateGroupSerializer, EditGroupSerializer,
JoinGroupRequestSerializer, GroupSerializer)
class GroupAdminAPIView(APIView):
def post(self, request):
"""
创建小组的api
---
request_serializer: CreateGroupSerializer
"""
serializer = CreateGroupSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
group = Group.objects.create(name=data["name"],
description=data["description"],
join_group_setting=data["join_group_setting"],
admin=request.user)
return success_response(GroupSerializer(group).data)
else:
return serializer_invalid_response(serializer)
def put(self, request):
"""
修改小组信息的api
---
request_serializer: EditGroupSerializer
"""
serializer = EditGroupSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
try:
group = Group.objects.get(id=data["id"], admin=request.user)
except Group.DoesNotExist:
return error_response(u"小组不存在")
group.name = data["name"]
group.description = data["description"]
group.join_group_setting = data["join_group_setting"]
group.save()
return success_response(GroupSerializer(group).data)
else:
return serializer_invalid_response(serializer)
def get(self, request):
"""
查询小组列表或者单个小组的信息
"""
group_id = request.GET.get("group_id", None)
if group_id:
try:
if request.user.admin_type == SUPER_ADMIN:
group = Group.object.get(id=group_id)
else:
group = Group.object.get(id=group_id, admin=request.user)
return success_response(GroupSerializer(group).data)
except Group.DoesNotExist:
return error_response(u"小组不存在")
else:
if request.user.admin_type == SUPER_ADMIN:
groups = Group.objects.filter(visible=True)
else:
groups = Group.objects.filter(admin=request.user, visible=True)
return paginate(request, groups, GroupSerializer)

View File

@@ -49,6 +49,7 @@ INSTALLED_APPS = (
'account',
'announcement',
'utils',
'group',
'rest_framework',
'rest_framework_swagger',
@@ -63,6 +64,7 @@ MIDDLEWARE_CLASSES = (
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'admin.middleware.AdminRequiredMiddleware'
)
ROOT_URLCONF = 'oj.urls'

View File

@@ -3,9 +3,11 @@ from django.conf.urls import include, url
from django.contrib import admin
from django.views.generic import TemplateView
from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, \
EmailCheckAPIView, UserAPIView, UserAdminAPIView
from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView,
UserChangePasswordAPIView, EmailCheckAPIView,
UserAPIView, UserAdminAPIView)
from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView
from group.views import GroupAdminAPIView
from admin.views import AdminTemplateView
urlpatterns = [
@@ -29,5 +31,6 @@ urlpatterns = [
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'^admin/template/(?P<template_dir>\w+)/(?P<template_name>\w+).html', AdminTemplateView.as_view(), name="admin_template")
url(r'^admin/template/(?P<template_dir>\w+)/(?P<template_name>\w+).html', AdminTemplateView.as_view(), name="admin_template"),
url(r'^api/admin/group/$', GroupAdminAPIView.as_view(), name="group_admin_api"),
]