From c25cdd672110534a5bcc007cc6bae09fa13c057e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Sun, 1 Nov 2020 21:20:16 +0800 Subject: [PATCH 01/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E3=80=81=E6=B3=A8=E5=86=8C=E3=80=81=E6=88=91=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/settings.py | 11 +++-- HomeWork/urls.py | 6 ++- common/__init__.py | 0 common/common.py | 12 ++++++ login/__init__.py | 0 login/admin.py | 6 +++ login/apps.py | 6 +++ login/migrations/__init__.py | 0 login/models.py | 7 ++++ login/serializers.py | 31 ++++++++++++++ login/tests.py | 3 ++ login/views.py | 81 ++++++++++++++++++++++++++++++++++++ work/__init__.py | 0 work/admin.py | 3 ++ work/apps.py | 5 +++ work/migrations/__init__.py | 0 work/models.py | 3 ++ work/tests.py | 3 ++ work/views.py | 3 ++ 19 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 common/__init__.py create mode 100644 common/common.py create mode 100644 login/__init__.py create mode 100644 login/admin.py create mode 100644 login/apps.py create mode 100644 login/migrations/__init__.py create mode 100644 login/models.py create mode 100644 login/serializers.py create mode 100644 login/tests.py create mode 100644 login/views.py create mode 100644 work/__init__.py create mode 100644 work/admin.py create mode 100644 work/apps.py create mode 100644 work/migrations/__init__.py create mode 100644 work/models.py create mode 100644 work/tests.py create mode 100644 work/views.py diff --git a/HomeWork/settings.py b/HomeWork/settings.py index c27ada7..116c92c 100644 --- a/HomeWork/settings.py +++ b/HomeWork/settings.py @@ -11,7 +11,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/ """ from pathlib import Path - +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -37,6 +37,8 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'login', + 'rest_framework', ] MIDDLEWARE = [ @@ -54,7 +56,8 @@ ROOT_URLCONF = 'HomeWork.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [os.path.join(BASE_DIR, 'templates')] + , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -103,9 +106,9 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/3.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'zh-hans' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Asia/Shanghai' USE_I18N = True diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 7ac1d03..228d6dc 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -15,7 +15,11 @@ Including another URLconf """ from django.contrib import admin from django.urls import path - +from login.views import LoginView,LogOutView,MeView urlpatterns = [ path('admin/', admin.site.urls), + path('login/',LoginView.as_view()), + path('logout/',LogOutView.as_view()), + path('me/',MeView.as_view()), + ] diff --git a/common/__init__.py b/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/common/common.py b/common/common.py new file mode 100644 index 0000000..241e197 --- /dev/null +++ b/common/common.py @@ -0,0 +1,12 @@ +import os +import configparser + +curpath = os.path.dirname(os.path.realpath(__file__)) +cfgpath = os.path.join(curpath, "./../main.ini") +conf = configparser.RawConfigParser() +conf.read(cfgpath, encoding="utf-8") + + +def get_first_error(errors): # 取出序列化抛出错误的一个错误,用于返回给用户 + for key, value in errors.items(): + return key, value diff --git a/login/__init__.py b/login/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/login/admin.py b/login/admin.py new file mode 100644 index 0000000..0c1424f --- /dev/null +++ b/login/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin + +# Register your models here. + + +admin.site.site_header = '1619001收作业系统-后台管理' diff --git a/login/apps.py b/login/apps.py new file mode 100644 index 0000000..43fa367 --- /dev/null +++ b/login/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BackendConfig(AppConfig): + name = 'login' + verbose_name="登录注册" diff --git a/login/migrations/__init__.py b/login/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/login/models.py b/login/models.py new file mode 100644 index 0000000..9ec13c0 --- /dev/null +++ b/login/models.py @@ -0,0 +1,7 @@ +from django.db import models + +# Create your models here. + + + + diff --git a/login/serializers.py b/login/serializers.py new file mode 100644 index 0000000..26b64ee --- /dev/null +++ b/login/serializers.py @@ -0,0 +1,31 @@ +from rest_framework import serializers +import re +from django.contrib.auth.models import User + + +class LoginSerializer(serializers.Serializer): # 用于登录的表单合法性验证,防止绕过前端验证 + username = serializers.CharField() + password = serializers.CharField() + remember = serializers.BooleanField() + + def validate_username(self, username): + if re.match("^[0-9]{9,9}$", username) is None: + raise serializers.ValidationError("用户名不符合规定") + else: + return username + + def validate_password(self, password): + if len(password) != 32: + raise serializers.ValidationError("密码长度不正确") + else: + return password + + +class UserSerializer(serializers.ModelSerializer): # 用于获取用户信息,反馈给用户 + name = serializers.SerializerMethodField() + def get_name(self, obj): + return obj.first_name + + class Meta: + model = User + fields = ['id','last_login', 'username','name', 'date_joined'] \ No newline at end of file diff --git a/login/tests.py b/login/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/login/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/login/views.py b/login/views.py new file mode 100644 index 0000000..c36cc62 --- /dev/null +++ b/login/views.py @@ -0,0 +1,81 @@ +from django.contrib import auth +from .serializers import LoginSerializer,UserSerializer +from rest_framework.views import APIView +from rest_framework.response import Response +import logging +from rest_framework.authentication import SessionAuthentication, BasicAuthentication +from common.common import get_first_error + + +class CsrfExemptSessionAuthentication(SessionAuthentication): + + def enforce_csrf(self, request): + return + + +logger = logging.getLogger(__name__) + + +class LoginView(APIView): # 登录相关视图类 + def post(self, request): # 用户登录,提交post数据 + context = dict() + data = LoginSerializer(data=request.POST) + if not data.is_valid(): # 验证有效性 + errors = data.errors + key, value = get_first_error(errors) + context['error'] = value[0] + context['err_code'] = 2002 + else: # 数据有效 + context['data'] = dict() + data = data.data + username = data['username'] + password = data['password'] + user = auth.authenticate(username=username, password=password) + if user is None: # 用户名或密码错误 + context['data']['error'] = "用户名或密码错误" + context['data']['result'] = False + else: # 验证通过 + auth.login(request, user) + context['data']['name'] = request.user.get_short_name() + context['data']['result'] = True + context['err_code'] = 0 + return Response(context) + + def get(self, request): # 检测用户是否登录 + context = dict() + if not request.user.is_anonymous: #已经登录 + context['err_code'] = 0 + context['data'] = dict() + context['data']['name'] = request.user.get_short_name() + context['data']['result'] = True + else: + context = dict() + context['err_code'] = 0 + context['data'] = dict() + context['data']['result'] = False + return Response(context) + + +class LogOutView(APIView): # 登出 + def get(self, request): + auth.logout(request) + context = dict() + context['err_code'] = 0 + context['data'] = dict() + context['data']['result'] = True + return Response(context) + + +class MeView(APIView): + def get(self, request): + context = dict() + context['err_code'] = 0 + if not request.user.is_authenticated: + context['err_code'] = 1001 + context['error'] = "您还未登录,请先登录" + return Response(context) + user = request.user + user_serializer = UserSerializer(user) + context['data'] = user_serializer.data + return Response(context) + diff --git a/work/__init__.py b/work/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/work/admin.py b/work/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/work/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/work/apps.py b/work/apps.py new file mode 100644 index 0000000..bfec31c --- /dev/null +++ b/work/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class WorkConfig(AppConfig): + name = 'work' diff --git a/work/migrations/__init__.py b/work/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/work/models.py b/work/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/work/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/work/tests.py b/work/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/work/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/work/views.py b/work/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/work/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. -- Gitee From 85d2afb60cbf0ec5ebba9f2e17ef27780b471ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Sun, 1 Nov 2020 21:25:27 +0800 Subject: [PATCH 02/24] =?UTF-8?q?=E6=B7=BB=E5=8A=A0README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..bafba9c --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# 1619001 收作业系统 后端 +## 技术栈 +Django 3.1.2 +Django Rest Framework 3.12.1 \ No newline at end of file -- Gitee From b7879033ee1a899a302064447fda092e3046c357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Sun, 1 Nov 2020 23:10:52 +0800 Subject: [PATCH 03/24] =?UTF-8?q?=E5=BB=BA=E7=AB=8B=E4=BD=9C=E4=B8=9A?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=95=B0=E6=8D=AE=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- login/apps.py | 2 +- work/__init__.py | 3 +++ work/admin.py | 12 ++++++++++++ work/apps.py | 1 + work/models.py | 12 ++++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/login/apps.py b/login/apps.py index 43fa367..a18114e 100644 --- a/login/apps.py +++ b/login/apps.py @@ -1,6 +1,6 @@ from django.apps import AppConfig -class BackendConfig(AppConfig): +class LoginConfig(AppConfig): name = 'login' verbose_name="登录注册" diff --git a/work/__init__.py b/work/__init__.py index e69de29..b9bcf9d 100644 --- a/work/__init__.py +++ b/work/__init__.py @@ -0,0 +1,3 @@ +from django.apps import AppConfig + +default_app_config='work.apps.WorkConfig' \ No newline at end of file diff --git a/work/admin.py b/work/admin.py index 8c38f3f..ee8381e 100644 --- a/work/admin.py +++ b/work/admin.py @@ -1,3 +1,15 @@ from django.contrib import admin +from .models import HomeWorkInfModel + # Register your models here. + +class HomeWorkAdmin(admin.ModelAdmin): + list_display = ['name', 'owner'] + list_display_links = ['name', 'owner'] + search_fields = ['name'] + readonly_fields = ['create_time'] + list_filter = ['owner', 'subject'] + + +admin.site.register(HomeWorkInfModel, HomeWorkAdmin) diff --git a/work/apps.py b/work/apps.py index bfec31c..c50da4b 100644 --- a/work/apps.py +++ b/work/apps.py @@ -3,3 +3,4 @@ from django.apps import AppConfig class WorkConfig(AppConfig): name = 'work' + verbose_name = "作业" \ No newline at end of file diff --git a/work/models.py b/work/models.py index 71a8362..f99b8aa 100644 --- a/work/models.py +++ b/work/models.py @@ -1,3 +1,15 @@ from django.db import models +from django.contrib.auth.models import User + # Create your models here. +class HomeWorkInfModel(models.Model): + class Meta: + db_table = "homeworkinformation" + verbose_name = "作业信息" + verbose_name_plural = verbose_name + name = models.CharField(max_length=50,verbose_name="作业名称") # 作业的名字 + create_time = models.DateTimeField(auto_now_add=True,verbose_name="创建时间") # 创建的时间 + subject = models.CharField(max_length=30,verbose_name="科目") + remark = models.CharField(max_length=500,verbose_name="备注",null=True,blank=True) + owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ReleaseHomeWork",verbose_name="创建人") -- Gitee From 4512b592d738c2dc4cf5430df734951566ff9eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 2 Nov 2020 12:50:28 +0800 Subject: [PATCH 04/24] =?UTF-8?q?=E4=BF=AE=E6=AD=A3gitignore=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 402676b..631d80f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ venv *.sqlite3 .idea +/*/migrations +*.pyc \ No newline at end of file -- Gitee From ddfd2e0a22d02740ebe8036168e7e100b94e80bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 2 Nov 2020 12:52:51 +0800 Subject: [PATCH 05/24] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=92=8C=E7=BC=93=E5=AD=98=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/__pycache__/__init__.cpython-36.pyc | Bin 131 -> 0 bytes HomeWork/__pycache__/settings.cpython-36.pyc | Bin 2230 -> 0 bytes HomeWork/__pycache__/urls.cpython-36.pyc | Bin 907 -> 0 bytes HomeWork/__pycache__/wsgi.cpython-36.pyc | Bin 536 -> 0 bytes login/migrations/__init__.py | 0 work/migrations/__init__.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 HomeWork/__pycache__/__init__.cpython-36.pyc delete mode 100644 HomeWork/__pycache__/settings.cpython-36.pyc delete mode 100644 HomeWork/__pycache__/urls.cpython-36.pyc delete mode 100644 HomeWork/__pycache__/wsgi.cpython-36.pyc delete mode 100644 login/migrations/__init__.py delete mode 100644 work/migrations/__init__.py diff --git a/HomeWork/__pycache__/__init__.cpython-36.pyc b/HomeWork/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 30038c20d33d7974dd9927302de5267741e8589f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmXr!<>k6)Hz%F}2p)q77+?f49Dul(1xTbY1T$zd`mJOr0tq9CUj}YgF$I++8TolJ p9{IVc;rT_`SQzo~nR%Hd@$q^EmA5!-a`RJ4b5iX)rjn-Lq%+c(Yh6{Q2^;&XzdtFK*^9kMcIY z^bcHs(>O>$+D>nq)quhWsaPxG-GMvXIeoz-xJv(-vU?vXFy3EJDG|Y6Z9e zOHhPmxCkq7$;@dN;Ig&^S4<9gxC+Q z3=P-x1WFjQT$2iYFA(-ThwOX7d%+L9A?Y!(P}n6d2@FO+=pG68VFX$?z_DC`G9zFU z&-+41kw%!XZi*Y?V?^&DspADiuw3MK3}$(*fd6b@VMNO&KVSl+FksB5FG?lwdQ=?8 zm}b!PoDy+MNLXT?Z}n(tnsI4N&jv*3hqf))7G;9hKiQGt0tO;hARHKWNa+8G6_EZ+ zpuh3VxwTZxw+uFj9)EncYOFqf@G#su2v?s!9lm=w+gIYTs z1W(oRT(La*_zzba^u;nRZ!B^+wov1(Rt)O0hz`Atjqi3MyvBAr+q{q-O!94oWnC9A8*KDcPWAiJLrEa9WLQH+6w9$}BbkdgV-GKgUY?h!Zn>5dIyK^&Y;c1A<-GXun6xH2o)B!G zm!J_kB(Qp?85W4U9#SpSQOi-jgcmx_OR2GTBhKkMUdFl}=X|{KY^xijv3PM_*OQAQ z(FcTj_5q2rKHeHG)AFw*MNSSgE+}%jEvx!#`L}qXBERbF#zm=CYwpVxeXpsgO1xZc zC@QK@fgPa4g?hD8smc3NTaK67&8Dh%+O=}Cu@f(n$sEY&t1HR5cdQ#IU!iZRMb9=~(JUEKR<`RCEji?{v}8+h*9X``MYOn;(8|0vG? z?068`16F^ipOe$7lF7pG~KxPnMrb$!9jhkH4p<+T|>tOXTH3Hj_MsJmSYs F_Fo*6?|c9N diff --git a/HomeWork/__pycache__/urls.cpython-36.pyc b/HomeWork/__pycache__/urls.cpython-36.pyc deleted file mode 100644 index 1fee39c72d13263ba11e544783a849ed0ed347ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 907 zcma)5&2H2%5O%WJZAn{r1>drfmW0w<1Qn=aMJ2?6A0e$OrQX=P$r9Vac3PGzufYrO zI9zk(#4B)O?9ECM0;!Q=jh*o~-}lYr?Bpc;asDkIjS%{Y1`q7fGkEnQSSVT`>QTS; zxWDi{8;|M{4;F!kSU>~jZ^oO+SAXp-4(RwTiYMfgkI+lW*$1gU;`eV};R`8N)w)&0 zR8oZDyOQDSR@DtLhAE-1ab0PHm23^u_JYPn;+u-y>IBcF!dxnbE3uM_I|$s=jA({6 zV_AsdDUE4#mZnq|I-wgP*0ND@!wQoWlBZ0hXUS=5WK$J7waF=z*J=3TGvR=xvvA&u z!m`_yb)csSeoiSS0$03|%48U?l;oIibJ8^Z;UNEUpYJ4tfPq4|3S!G?6wP{FCHOPL zf^haUvT+oL7d6rP;Sz+=0qXx)NK-Opi6qXbJss=2V}D0BHa{Ucw;scjipFGuve?*C`mduN2t> zha1Il_zPwg#a=filve_Rz&ieA;<3bC{1jU)=90ffA#trGjxq-O+%jvVTAq z=*qAzu*AEgK{LN2bq~I~<@ao!T{T-%N^xbav?KqIz+xoLwmW>nC2ebV{r~{<1eU-% I_Krt?0GF5>iU0rr diff --git a/HomeWork/__pycache__/wsgi.cpython-36.pyc b/HomeWork/__pycache__/wsgi.cpython-36.pyc deleted file mode 100644 index d67e5ece69bdda5184c12f0a0b656b9d7f5b6de4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536 zcmZut!A=`75cPTkiI!5eQq{AskzkjK8>&!|fHW0^LqJFolH;x?8>e2+YHdQpm9MDO zAL!@whJ5A3FL1(16e$NR`FZT|y!U4Ix3`o3hkyB>h>$0;w&DA3d8)419V+q$-|6)~* z6UbefBwfegcZC)#b7Nr33Zb?5seuX01S?VAYS`5<1Iy<@l zxN1MO;G8mrZ8v?B^WcGVPtp1hODAa_8c657H4RF>31+HlG(HK15=P=yJHNFi`H$2| r__% Date: Mon, 2 Nov 2020 19:13:09 +0800 Subject: [PATCH 06/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E5=8F=8A=E6=B7=BB=E5=8A=A0=E4=BD=9C=E4=B8=9A=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/settings.py | 3 +- HomeWork/urls.py | 2 ++ login/views.py | 2 +- work/models.py | 19 +++++++---- work/serializers.py | 50 +++++++++++++++++++++++++++ work/views.py | 80 +++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 147 insertions(+), 9 deletions(-) create mode 100644 work/serializers.py diff --git a/HomeWork/settings.py b/HomeWork/settings.py index 116c92c..5be5252 100644 --- a/HomeWork/settings.py +++ b/HomeWork/settings.py @@ -25,7 +25,7 @@ SECRET_KEY = 'x7(a(2*+u=vu(86j^+j=^3xo94m3*bf^-p1_dvhv=768@5=g@@' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*'] # Application definition @@ -39,6 +39,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'login', 'rest_framework', + 'work' ] MIDDLEWARE = [ diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 228d6dc..c43b9bb 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -16,10 +16,12 @@ Including another URLconf from django.contrib import admin from django.urls import path from login.views import LoginView,LogOutView,MeView +from work.views import HomeWorkView urlpatterns = [ path('admin/', admin.site.urls), path('login/',LoginView.as_view()), path('logout/',LogOutView.as_view()), path('me/',MeView.as_view()), + path('homework/',HomeWorkView.as_view()), ] diff --git a/login/views.py b/login/views.py index c36cc62..b2805f8 100644 --- a/login/views.py +++ b/login/views.py @@ -3,7 +3,7 @@ from .serializers import LoginSerializer,UserSerializer from rest_framework.views import APIView from rest_framework.response import Response import logging -from rest_framework.authentication import SessionAuthentication, BasicAuthentication +from rest_framework.authentication import SessionAuthentication from common.common import get_first_error diff --git a/work/models.py b/work/models.py index f99b8aa..9416d05 100644 --- a/work/models.py +++ b/work/models.py @@ -1,6 +1,6 @@ from django.db import models from django.contrib.auth.models import User - +import datetime # Create your models here. class HomeWorkInfModel(models.Model): @@ -8,8 +8,15 @@ class HomeWorkInfModel(models.Model): db_table = "homeworkinformation" verbose_name = "作业信息" verbose_name_plural = verbose_name - name = models.CharField(max_length=50,verbose_name="作业名称") # 作业的名字 - create_time = models.DateTimeField(auto_now_add=True,verbose_name="创建时间") # 创建的时间 - subject = models.CharField(max_length=30,verbose_name="科目") - remark = models.CharField(max_length=500,verbose_name="备注",null=True,blank=True) - owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ReleaseHomeWork",verbose_name="创建人") + def __str__(self): + return self.name + name = models.CharField(max_length=50, verbose_name="作业名称") # 作业的名字 + type=models.CharField(max_length=100,choices=(('file',"文件"),('hypertext',"超文本")),default="hypertext",verbose_name="作业类型") + create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") # 创建的时间 + subject = models.CharField(max_length=30, verbose_name="科目") + remark = models.CharField(max_length=500, verbose_name="备注", null=True, blank=True) + owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ReleaseHomeWork", verbose_name="创建人") + end_time = models.DateTimeField(verbose_name="截止时间",default=datetime.datetime.now()) + member_can_know_donelist = models.BooleanField(verbose_name="成员可查看完成情况", choices=((False, "否"), (True, "是")),default=False) + member_can_see_others = models.BooleanField(verbose_name="成员可互相查看作业", choices=((False, "否"), (True, "是")), + default=False) diff --git a/work/serializers.py b/work/serializers.py new file mode 100644 index 0000000..fd92788 --- /dev/null +++ b/work/serializers.py @@ -0,0 +1,50 @@ +from rest_framework import serializers +from .models import HomeWorkInfModel + + +class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法性验证,防止绕过前端验证 + name = serializers.CharField() + type = serializers.CharField() + subject = serializers.CharField() + remark = serializers.CharField(required=False) + end_time = serializers.CharField() + member_can_know_donelist = serializers.CharField() + member_can_see_others = serializers.CharField() + + def validate_name(self, name): + if len(name) > 50: + raise serializers.ValidationError("名称长度过长") + return name + + def validate_type(self, type): + types = ['file', 'hypertext'] + if type not in types: + raise serializers.ValidationError("不支持的类型") + return type + + def validate_subject(self, subject): + if len(subject) > 30: + raise serializers.ValidationError("科目过长") + return subject + + def validate_remark(self, remark): + if len(remark) > 500: + raise serializers.ValidationError("备注过长") + return remark + + def validate_end_time(self, end_time): + try: + int(end_time[0:4]) + int(end_time[5:7]) + int(end_time[8:10]) + int(end_time[11:13]) + int(end_time[14:16]) + return end_time + except: + raise serializers.ValidationError("日期格式不正确") + + +class HomeWorkInfSerializer(serializers.ModelSerializer): + class Meta: + model = HomeWorkInfModel + fields = '__all__' diff --git a/work/views.py b/work/views.py index 91ea44a..c17e8b0 100644 --- a/work/views.py +++ b/work/views.py @@ -1,3 +1,81 @@ -from django.shortcuts import render +from rest_framework.views import APIView +from rest_framework.response import Response +from .serializers import HomeWorkSerializer,HomeWorkInfSerializer +from common.common import get_first_error +from .models import HomeWorkInfModel +from datetime import datetime +from rest_framework.authentication import SessionAuthentication, BasicAuthentication + +class CsrfExemptSessionAuthentication(SessionAuthentication): + + def enforce_csrf(self, request): + return # Create your views here. +from django.views.decorators.csrf import csrf_exempt + + +class HomeWorkView(APIView): + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) + + def post(self, request): + context = dict() + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + data = HomeWorkSerializer(data=request.POST) + if not data.is_valid(): # 验证有效性 + errors = data.errors + key, value = get_first_error(errors) + context['error'] = key + ' ' + value[0] + context['err_code'] = 2002 + return Response(context) + else: + context['err_code'] = 0 + data=data.data + end_time=data['end_time'] + HomeWorkInfModel.objects.create(name=data['name'], + type=data['type'], + subject=data['subject'], + remark=data.get('remark') if data.get('remark') else '', + owner=user, + member_can_know_donelist=True if data['member_can_know_donelist']=='true' else False, + member_can_see_others=True if data['member_can_see_others']=='true' else False, + end_time=datetime(year=int(end_time[0:4]), + month=int(end_time[5:7]), + day=int(end_time[8:10]), + hour=int(end_time[11:13]), + minute=int(end_time[14:16]) + ) + ) + return Response(context) + + def get(self, request): + context = dict() + id = request.GET.get('id') + if id is None: # 验证有效性 + context['error'] = "没有请求的作业id" + context['err_code'] = 2002 + return Response(context) + else: + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + query = HomeWorkInfModel.objects.filter(id=id) + if not query.exists(): # 请求数据不存在 + context['err_code'] = 4004 + context['error'] = "无法找到您要的数据" + return Response(context) + query = query.first() + context['data'] = HomeWorkInfSerializer(query).data + return Response(context) + def put(self, request): + pass + + def delete(self, request): + pass -- Gitee From 5f0d4f347e9c10b0d8c30171657cb2247966704a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 2 Nov 2020 20:23:22 +0800 Subject: [PATCH 07/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E7=BC=96?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E5=88=A0=E9=99=A4=E4=BD=9C=E4=B8=9A=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work/serializers.py | 3 ++ work/views.py | 109 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 6 deletions(-) diff --git a/work/serializers.py b/work/serializers.py index fd92788..1f974cc 100644 --- a/work/serializers.py +++ b/work/serializers.py @@ -45,6 +45,9 @@ class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法 class HomeWorkInfSerializer(serializers.ModelSerializer): + owner =serializers.SerializerMethodField() class Meta: model = HomeWorkInfModel fields = '__all__' + def get_owner(self,obj): + return obj.owner.first_name diff --git a/work/views.py b/work/views.py index c17e8b0..f2dedee 100644 --- a/work/views.py +++ b/work/views.py @@ -5,14 +5,12 @@ from common.common import get_first_error from .models import HomeWorkInfModel from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication - +from django.http import QueryDict class CsrfExemptSessionAuthentication(SessionAuthentication): def enforce_csrf(self, request): return -# Create your views here. -from django.views.decorators.csrf import csrf_exempt class HomeWorkView(APIView): @@ -36,7 +34,7 @@ class HomeWorkView(APIView): context['err_code'] = 0 data=data.data end_time=data['end_time'] - HomeWorkInfModel.objects.create(name=data['name'], + homework=HomeWorkInfModel.objects.create(name=data['name'], type=data['type'], subject=data['subject'], remark=data.get('remark') if data.get('remark') else '', @@ -50,10 +48,17 @@ class HomeWorkView(APIView): minute=int(end_time[14:16]) ) ) + context['data']=dict() + context['data']['id']=homework.id return Response(context) def get(self, request): context = dict() + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) id = request.GET.get('id') if id is None: # 验证有效性 context['error'] = "没有请求的作业id" @@ -72,10 +77,102 @@ class HomeWorkView(APIView): context['error'] = "无法找到您要的数据" return Response(context) query = query.first() + context['err_code']=0 context['data'] = HomeWorkInfSerializer(query).data + if user == query.owner: + context['data'].update({'is_creater':True}) + else: + context['data'].update({'is_creater': False}) return Response(context) def put(self, request): - pass + context = dict() + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + put_data= QueryDict(request.body) + data = HomeWorkSerializer(data=put_data) + if not data.is_valid(): # 验证有效性 + errors = data.errors + key, value = get_first_error(errors) + context['error'] = key + ' ' + value[0] + context['err_code'] = 2002 + return Response(context) + else: + context['err_code'] = 0 + data = data.data + end_time = data['end_time'] + id=put_data.get('id') + if id is None: + context['error'] = "没有请求的作业id" + context['err_code'] = 2002 + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + query = HomeWorkInfModel.objects.filter(id=id) + if not query.exists(): # 请求数据不存在 + context['err_code'] = 4004 + context['error'] = "无法找到您要的数据" + return Response(context) + query = query.first() + if user != query.owner: + context['err_code'] = 4003 + context['error'] = "您无权执行此操作" + return Response(context) + HomeWorkInfModel.objects.update(name=data['name'], + type=data['type'], + subject=data['subject'], + remark=data.get('remark') if data.get('remark') else '', + owner=user, + member_can_know_donelist=True if data[ + 'member_can_know_donelist'] == 'true' else False, + member_can_see_others=True if data[ + 'member_can_see_others'] == 'true' else False, + end_time=datetime(year=int(end_time[0:4]), + month=int(end_time[5:7]), + day=int(end_time[8:10]), + hour=int(end_time[11:13]), + minute=int(end_time[14:16]) + ) + ) + return Response(context) def delete(self, request): - pass + context = dict() + context['err_code'] = 0 + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + + + data = QueryDict(request.body) + id = data.get('id') + if id is None: + context['error'] = "没有请求的作业id" + context['err_code'] = 2002 + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + query = HomeWorkInfModel.objects.filter(id=id) + if not query.exists(): # 请求数据不存在 + context['err_code'] = 4004 + context['error'] = "无法找到您要的数据" + return Response(context) + query = query.first() + if user != query.owner: + context['err_code'] = 4003 + context['error'] = "您无权执行此操作" + return Response(context) + query.delete() + return Response(context) \ No newline at end of file -- Gitee From 708272bcd7284e035e68cb3e9d264d041799cc0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Tue, 3 Nov 2020 23:27:28 +0800 Subject: [PATCH 08/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E4=BD=9C=E4=B8=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/urls.py | 5 ++-- README.md | 5 +++- work/serializers.py | 28 ++++++++++++++++++-- work/views.py | 64 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/HomeWork/urls.py b/HomeWork/urls.py index c43b9bb..75ab6d9 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -16,12 +16,13 @@ Including another URLconf from django.contrib import admin from django.urls import path from login.views import LoginView,LogOutView,MeView -from work.views import HomeWorkView +from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView urlpatterns = [ path('admin/', admin.site.urls), path('login/',LoginView.as_view()), path('logout/',LogOutView.as_view()), path('me/',MeView.as_view()), path('homework/',HomeWorkView.as_view()), - + path('myhomeworknum/',MyHomeWorkNumView.as_view()), + path('myhomework/',MyHomeWorkView.as_view()), ] diff --git a/README.md b/README.md index bafba9c..74bf214 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # 1619001 收作业系统 后端 ## 技术栈 -Django 3.1.2 +Django Rest Framework 3.12.1 \ No newline at end of file +Django 3.1.2 +Django Rest Framework 3.12.1 +## 返回说明 +本项目利用Django Rest Framework提供API,并遵循以下原则: +每个api必定返回err_code,用来标识本次操作结果,err_code=表示请求成功。 \ No newline at end of file diff --git a/work/serializers.py b/work/serializers.py index 1f974cc..3509234 100644 --- a/work/serializers.py +++ b/work/serializers.py @@ -45,9 +45,33 @@ class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法 class HomeWorkInfSerializer(serializers.ModelSerializer): - owner =serializers.SerializerMethodField() + owner = serializers.SerializerMethodField() + class Meta: model = HomeWorkInfModel fields = '__all__' - def get_owner(self,obj): + + def get_owner(self, obj): + return obj.owner.first_name + + +class HomeWorkAllSerializer(serializers.ModelSerializer): + class Meta: + model = HomeWorkInfModel + fields = ['id','name', 'end_time', 'owner','subject','end_time'] + + owner = serializers.SerializerMethodField() + + def get_owner(self, obj): + return obj.owner.first_name + + +class HomeWorkCreateSerializer(serializers.ModelSerializer): + class Meta: + model = HomeWorkInfModel + fields = ['id','name', 'end_time', 'owner','subject','end_time'] + + owner = serializers.SerializerMethodField() + + def get_owner(self, obj): return obj.owner.first_name diff --git a/work/views.py b/work/views.py index f2dedee..41bc4d0 100644 --- a/work/views.py +++ b/work/views.py @@ -1,6 +1,6 @@ from rest_framework.views import APIView from rest_framework.response import Response -from .serializers import HomeWorkSerializer,HomeWorkInfSerializer +from .serializers import HomeWorkSerializer,HomeWorkInfSerializer,HomeWorkAllSerializer,HomeWorkCreateSerializer from common.common import get_first_error from .models import HomeWorkInfModel from datetime import datetime @@ -175,4 +175,66 @@ class HomeWorkView(APIView): context['error'] = "您无权执行此操作" return Response(context) query.delete() + return Response(context) + + +class MyHomeWorkNumView(APIView): + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + status = data.get('status') + if status is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + if status == "member": + context['data'] = HomeWorkInfModel.objects.filter().count() + elif status == "owner": + context['data'] = HomeWorkInfModel.objects.filter(owner=user).count() + else: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + return Response(context) + + +class MyHomeWorkView(APIView): + + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + status = data.get('status') + try: + start = int(data.get('start')) - 1 + end = int(data.get('end')) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + if status is None or start is None or end is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + if status == "member": + work = HomeWorkInfModel.objects.order_by('-end_time').filter()[start:end] + context['data'] = HomeWorkAllSerializer(work, many=True).data + elif status == "owner": + work = HomeWorkInfModel.objects.order_by('-end_time').filter(owner=user)[start:end] + context['data'] = HomeWorkCreateSerializer(work, many=True).data + else: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) return Response(context) \ No newline at end of file -- Gitee From 7d79d79e85bd106a5cec14f93bc5a212fdfefb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Wed, 4 Nov 2020 23:59:44 +0800 Subject: [PATCH 09/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/settings.py | 2 +- HomeWork/urls.py | 3 +- work/admin.py | 7 +++- work/models.py | 27 ++++++++++-- work/views.py | 98 +++++++++++++++++++++++++++++++++----------- 5 files changed, 105 insertions(+), 32 deletions(-) diff --git a/HomeWork/settings.py b/HomeWork/settings.py index 5be5252..c467bfe 100644 --- a/HomeWork/settings.py +++ b/HomeWork/settings.py @@ -46,7 +46,7 @@ MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', + # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 75ab6d9..6114a0b 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -16,7 +16,7 @@ Including another URLconf from django.contrib import admin from django.urls import path from login.views import LoginView,LogOutView,MeView -from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView +from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView urlpatterns = [ path('admin/', admin.site.urls), path('login/',LoginView.as_view()), @@ -25,4 +25,5 @@ urlpatterns = [ path('homework/',HomeWorkView.as_view()), path('myhomeworknum/',MyHomeWorkNumView.as_view()), path('myhomework/',MyHomeWorkView.as_view()), + path('submit/',SubmitView.as_view(),), ] diff --git a/work/admin.py b/work/admin.py index ee8381e..a72f927 100644 --- a/work/admin.py +++ b/work/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import HomeWorkInfModel +from .models import HomeWorkInfModel, DoneModel # Register your models here. @@ -12,4 +12,9 @@ class HomeWorkAdmin(admin.ModelAdmin): list_filter = ['owner', 'subject'] +class DoneAdmin(admin.ModelAdmin): + list_display = ['work'] + + admin.site.register(HomeWorkInfModel, HomeWorkAdmin) +admin.site.register(DoneModel, DoneAdmin) diff --git a/work/models.py b/work/models.py index 9416d05..9267b27 100644 --- a/work/models.py +++ b/work/models.py @@ -2,21 +2,40 @@ from django.db import models from django.contrib.auth.models import User import datetime + # Create your models here. class HomeWorkInfModel(models.Model): class Meta: db_table = "homeworkinformation" verbose_name = "作业信息" verbose_name_plural = verbose_name + def __str__(self): return self.name + name = models.CharField(max_length=50, verbose_name="作业名称") # 作业的名字 - type=models.CharField(max_length=100,choices=(('file',"文件"),('hypertext',"超文本")),default="hypertext",verbose_name="作业类型") + type = models.CharField(max_length=100, choices=(('file', "文件"), ('hypertext', "超文本")), default="hypertext", + verbose_name="作业类型") create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") # 创建的时间 subject = models.CharField(max_length=30, verbose_name="科目") remark = models.CharField(max_length=500, verbose_name="备注", null=True, blank=True) owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ReleaseHomeWork", verbose_name="创建人") - end_time = models.DateTimeField(verbose_name="截止时间",default=datetime.datetime.now()) - member_can_know_donelist = models.BooleanField(verbose_name="成员可查看完成情况", choices=((False, "否"), (True, "是")),default=False) - member_can_see_others = models.BooleanField(verbose_name="成员可互相查看作业", choices=((False, "否"), (True, "是")), + end_time = models.DateTimeField(verbose_name="截止时间", default=datetime.datetime.now()) + member_can_know_donelist = models.BooleanField(verbose_name="成员可查看完成情况", choices=((False, "否"), (True, "是")), default=False) + member_can_see_others = models.BooleanField(verbose_name="成员可互相查看作业", choices=((False, "否"), (True, "是")), + default=False) + + +class DoneModel(models.Model): + class Meta: + db_table = "done" + verbose_name = "作业完成情况" + verbose_name_plural = verbose_name + + def __str__(self): + return self.work + + work = models.ForeignKey(to=HomeWorkInfModel, verbose_name="作业", on_delete=models.CASCADE, related_name='done') + owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Done", verbose_name="创建人") + create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") # 创建的时间 diff --git a/work/views.py b/work/views.py index 41bc4d0..ca0d261 100644 --- a/work/views.py +++ b/work/views.py @@ -1,11 +1,13 @@ from rest_framework.views import APIView from rest_framework.response import Response -from .serializers import HomeWorkSerializer,HomeWorkInfSerializer,HomeWorkAllSerializer,HomeWorkCreateSerializer +from .serializers import HomeWorkSerializer, HomeWorkInfSerializer, HomeWorkAllSerializer, HomeWorkCreateSerializer from common.common import get_first_error from .models import HomeWorkInfModel from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication from django.http import QueryDict +import os + class CsrfExemptSessionAuthentication(SessionAuthentication): @@ -32,24 +34,26 @@ class HomeWorkView(APIView): return Response(context) else: context['err_code'] = 0 - data=data.data - end_time=data['end_time'] - homework=HomeWorkInfModel.objects.create(name=data['name'], - type=data['type'], - subject=data['subject'], - remark=data.get('remark') if data.get('remark') else '', - owner=user, - member_can_know_donelist=True if data['member_can_know_donelist']=='true' else False, - member_can_see_others=True if data['member_can_see_others']=='true' else False, - end_time=datetime(year=int(end_time[0:4]), - month=int(end_time[5:7]), - day=int(end_time[8:10]), - hour=int(end_time[11:13]), - minute=int(end_time[14:16]) - ) - ) - context['data']=dict() - context['data']['id']=homework.id + data = data.data + end_time = data['end_time'] + homework = HomeWorkInfModel.objects.create(name=data['name'], + type=data['type'], + subject=data['subject'], + remark=data.get('remark') if data.get('remark') else '', + owner=user, + member_can_know_donelist=True if data[ + 'member_can_know_donelist'] == 'true' else False, + member_can_see_others=True if data[ + 'member_can_see_others'] == 'true' else False, + end_time=datetime(year=int(end_time[0:4]), + month=int(end_time[5:7]), + day=int(end_time[8:10]), + hour=int(end_time[11:13]), + minute=int(end_time[14:16]) + ) + ) + context['data'] = dict() + context['data']['id'] = homework.id return Response(context) def get(self, request): @@ -77,13 +81,14 @@ class HomeWorkView(APIView): context['error'] = "无法找到您要的数据" return Response(context) query = query.first() - context['err_code']=0 + context['err_code'] = 0 context['data'] = HomeWorkInfSerializer(query).data if user == query.owner: - context['data'].update({'is_creater':True}) + context['data'].update({'is_creater': True}) else: context['data'].update({'is_creater': False}) return Response(context) + def put(self, request): context = dict() user = request.user @@ -91,7 +96,7 @@ class HomeWorkView(APIView): context['err_code'] = 1001 context['error'] = "您还未登录" return Response(context) - put_data= QueryDict(request.body) + put_data = QueryDict(request.body) data = HomeWorkSerializer(data=put_data) if not data.is_valid(): # 验证有效性 errors = data.errors @@ -103,7 +108,7 @@ class HomeWorkView(APIView): context['err_code'] = 0 data = data.data end_time = data['end_time'] - id=put_data.get('id') + id = put_data.get('id') if id is None: context['error'] = "没有请求的作业id" context['err_code'] = 2002 @@ -151,7 +156,6 @@ class HomeWorkView(APIView): context['error'] = "您还未登录" return Response(context) - data = QueryDict(request.body) id = data.get('id') if id is None: @@ -205,6 +209,7 @@ class MyHomeWorkNumView(APIView): class MyHomeWorkView(APIView): + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) def get(self, request): context = dict() @@ -237,4 +242,47 @@ class MyHomeWorkView(APIView): context['err_code'] = 2001 context['error'] = "请求参数不正确" return Response(context) - return Response(context) \ No newline at end of file + return Response(context) + + +class SubmitView(APIView): + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) + + def post(self, request): + context = dict() + context['err_code'] = 0 + data = request.POST + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + work_id = data.get('work_id') + try: + work_id = int(work_id) + except: + context['err_code'] = 1002 + context['error'] = "请求参数不正确" + return Response(context) + work = HomeWorkInfModel.objects.filter(id=work_id) + if not work.exists(): + context['err_code'] = 4004 + context['error'] = "无法找到您提交的作业" + return Response(context) + work = work.first() + + file = request.FILES.get("file") # 获取上传的文件,如果没有文件,则默认为None + if not file: + context['err_code'] = 2001 + context['error'] = "没有文件" + return Response(context) + dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), + str(work.id) + work.name) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + path = os.path.join(dir_path, user.username + user.first_name + os.path.splitext(file.name)[1]) + destination = open(path, 'wb+') + for chunk in file.chunks(): + destination.write(chunk) + destination.close() + return Response(context) -- Gitee From 6c6402d424160117f4ed27799472d3590a4e566f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 9 Nov 2020 17:26:36 +0800 Subject: [PATCH 10/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/settings.py | 3 +- HomeWork/urls.py | 7 +- group/__init__.py | 1 + group/admin.py | 25 ++++ group/apps.py | 6 + group/models.py | 52 ++++++++ group/serializers.py | 72 +++++++++++ group/tests.py | 3 + group/views.py | 286 +++++++++++++++++++++++++++++++++++++++++++ login/serializers.py | 24 +++- login/views.py | 48 +++++++- work/models.py | 2 + 12 files changed, 524 insertions(+), 5 deletions(-) create mode 100644 group/__init__.py create mode 100644 group/admin.py create mode 100644 group/apps.py create mode 100644 group/models.py create mode 100644 group/serializers.py create mode 100644 group/tests.py create mode 100644 group/views.py diff --git a/HomeWork/settings.py b/HomeWork/settings.py index c467bfe..d2b9c92 100644 --- a/HomeWork/settings.py +++ b/HomeWork/settings.py @@ -39,7 +39,8 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'login', 'rest_framework', - 'work' + 'work', + 'group', ] MIDDLEWARE = [ diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 6114a0b..a69c3c9 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -15,8 +15,9 @@ Including another URLconf """ from django.contrib import admin from django.urls import path -from login.views import LoginView,LogOutView,MeView +from login.views import LoginView,LogOutView,MeView,RegisterView from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView +from group.views import GroupView,MyGroupNumView,MyGroupView urlpatterns = [ path('admin/', admin.site.urls), path('login/',LoginView.as_view()), @@ -26,4 +27,8 @@ urlpatterns = [ path('myhomeworknum/',MyHomeWorkNumView.as_view()), path('myhomework/',MyHomeWorkView.as_view()), path('submit/',SubmitView.as_view(),), + path('group/',GroupView.as_view()), + path('mygroup/',MyGroupView.as_view()), + path('mygroupnum',MyGroupNumView.as_view()), + path('register/',RegisterView.as_view()), ] diff --git a/group/__init__.py b/group/__init__.py new file mode 100644 index 0000000..e26f747 --- /dev/null +++ b/group/__init__.py @@ -0,0 +1 @@ +default_app_config='group.apps.GroupConfig' \ No newline at end of file diff --git a/group/admin.py b/group/admin.py new file mode 100644 index 0000000..bfa3fca --- /dev/null +++ b/group/admin.py @@ -0,0 +1,25 @@ +from django.contrib import admin +from .models import GroupModel, GroupMembersModel, WorkGroupModel + + +# Register your models here. +class GroupAdmin(admin.ModelAdmin): + list_display_links = ['name', 'owner'] + search_fields = ['owner__username'] + list_display = ['name', 'owner'] + + +class GroupMembersAdmin(admin.ModelAdmin): + list_display_links = ['group', 'user'] + search_fields = ['group__name', 'user__first_name'] + list_display = ['group', 'user'] + + +class WorkGroupAdmin(admin.ModelAdmin): + list_display_links = ['group', 'work'] + list_display = ['group', 'work'] + + +admin.site.register(GroupModel, GroupAdmin) +admin.site.register(GroupMembersModel, GroupMembersAdmin) +admin.site.register(WorkGroupModel, WorkGroupAdmin) diff --git a/group/apps.py b/group/apps.py new file mode 100644 index 0000000..1f41813 --- /dev/null +++ b/group/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class GroupConfig(AppConfig): + name = 'group' + verbose_name="小组" \ No newline at end of file diff --git a/group/models.py b/group/models.py new file mode 100644 index 0000000..3eb1f25 --- /dev/null +++ b/group/models.py @@ -0,0 +1,52 @@ +from django.db import models +from django.contrib.auth.models import User +from work.models import HomeWorkInfModel + + +# Create your models here. +class GroupModel(models.Model): + class Meta: + db_table = "user_group" + verbose_name = "分组" + verbose_name_plural = verbose_name + + name = models.CharField(max_length=30, verbose_name="组名", db_index=True) + desc = models.TextField('描述', default='', blank=True, null=True, max_length=200) + owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='创建人', related_name="own_groups", + db_index=True) + password = models.CharField(max_length=20, verbose_name="小组密码", null=True) + create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True) + + def __str__(self): + return str(self.name) + + def get_all_members(self): + yield self.owner + join_groups = GroupMembersModel.objects.filter(group=self) + for member in join_groups: + yield member.user + + +class GroupMembersModel(models.Model): + class Meta: + db_table = "group_members" + verbose_name = "小组成员" + verbose_name_plural = verbose_name + + user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户", related_name="joined_groups", + db_index=True) + group = models.ForeignKey(GroupModel, on_delete=models.CASCADE, verbose_name="小组", related_name="members") + time = models.DateTimeField(auto_now_add=True, verbose_name="加入时间") + + def __str__(self): + return "{}-{}".format(self.group,self.user.first_name) + + +class WorkGroupModel(models.Model): + class Meta: + db_table = "homeworkgroup" + verbose_name = "作业小组" + verbose_name_plural = verbose_name + + group = models.ForeignKey(GroupModel, on_delete=models.CASCADE, verbose_name="小组", related_name="work") + work = models.ForeignKey(HomeWorkInfModel, on_delete=models.CASCADE, verbose_name="作业", related_name="groups") diff --git a/group/serializers.py b/group/serializers.py new file mode 100644 index 0000000..ff0a1cc --- /dev/null +++ b/group/serializers.py @@ -0,0 +1,72 @@ +from rest_framework import serializers +from .models import GroupModel +import re + + +class GroupSerializer(serializers.ModelSerializer): + members = serializers.SerializerMethodField() + + class Meta: + model = GroupModel + fields = ['id', 'name', 'desc', 'create_time', 'owner', 'members', 'password'] + + def get_members(self, obj): + members_list=list() + members=obj.get_members() + for member in members: + members_list.append({'id':member.id,'name':member.first_name}) + return members_list + + +class GroupUnSerializer(serializers.Serializer): + name = serializers.CharField() + desc = serializers.CharField() + password = serializers.CharField() + + def validate_name(self, name): + if valid_group_information('name', name): + return name + else: + raise serializers.ValidationError("组名格式不正确") + + def validate_desc(self, desc): + if valid_group_information('desc', desc): + return desc + else: + raise serializers.ValidationError("描述格式不正确") + + def validate_password(self, password): + if valid_group_information('password', password): + return password + else: + raise serializers.ValidationError("密码格式不正确") + + +def valid_group_information(name, data): + if name == 'name': + return re.match("^[a-zA-Z0-9\u4e00-\u9fa5_丶]{1,20}$", data) is not None + if name == 'desc': + return re.match("^[a-zA-Z0-9\u4e00-\u9fa5_丶]{5,200}$", data) is not None + if name == 'password': + return re.match("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$", data) is not None + + +class GroupsSerializer(serializers.Serializer): + id = serializers.SerializerMethodField() + time = serializers.DateTimeField() + name = serializers.SerializerMethodField() + + def get_id(self, obj): + return obj.group.id + + def get_name(self, obj): + return obj.group.name + + +class CreateGroupsSerializer(serializers.Serializer): + id = serializers.IntegerField() + time = serializers.SerializerMethodField() + name = serializers.CharField() + + def get_time(self, obj): + return obj.create_time diff --git a/group/tests.py b/group/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/group/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/group/views.py b/group/views.py new file mode 100644 index 0000000..8d221d6 --- /dev/null +++ b/group/views.py @@ -0,0 +1,286 @@ +from rest_framework.views import APIView, Response +from .serializers import GroupSerializer, GroupsSerializer, CreateGroupsSerializer, GroupUnSerializer, \ + valid_group_information +from .models import GroupModel, GroupMembersModel +from common.common import get_first_error +from rest_framework.authentication import SessionAuthentication, BasicAuthentication +from django.http import QueryDict + + +class CsrfExemptSessionAuthentication(SessionAuthentication): + + def enforce_csrf(self, request): + return + + +class GroupView(APIView): + + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) + + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + id = data.get('id') + if id is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + query = GroupModel.objects.filter(id=id) + if not query.exists(): # 请求数据不存在 + context['err_code'] = 3004 + context['error'] = "无法找到您要的数据" + return Response(context) + group = query.first() + is_member = GroupMembersModel.objects.filter(user=user, group=group).exists() + is_owner = (group.owner == user) + if not is_member and not is_owner: + context['err_code'] = 3003 + context['error'] = "您无权查看此内容" + return Response(context) + context['data'] = GroupSerializer(group).data + if not is_owner: + del context['data']['password'] + context['data']['is_owner'] = is_owner + return Response(context) + + def post(self, request): + context = dict() + context['err_code'] = 0 + data = request.POST + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + data = GroupUnSerializer(data=data) + if not data.is_valid(): # 验证有效性 + errors = data.errors + key, value = get_first_error(errors) + context['error'] = value[0] + context['err_code'] = 2002 + return Response(context) + data = data.data + GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password']) + return Response(context) + + def put(self, request): + context = dict() + context['err_code'] = 0 + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + data = QueryDict(request.body) + id = data.get('id') + if id is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + password = data.get('password') + name = data.get('name') + desc = data.get('desc') + delete_user_id = data.get('delete_user_id') + if password is None and name is None and desc is None and delete_user_id is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + group = GroupModel.objects.filter(id=id) + if not group.exists(): + context['err_code'] = 4004 + context['error'] = "该小组不存在" + return Response(context) + group = group.first() + if user != group.owner: + context['err_code'] = 4003 + context['error'] = "您无权操作" + return Response(context) + if password is not None: + if not valid_group_information('password', password): + context['err_code'] = 2002 + context['error'] = "格式不正确" + return Response(context) + group.password = password + if name is not None: + if not valid_group_information('name', name): + context['err_code'] = 2002 + context['error'] = "格式不正确" + return Response(context) + group.name = name + if desc is not None: + if not valid_group_information('desc', desc): + context['err_code'] = 2002 + context['error'] = "格式不正确" + return Response(context) + group.desc = desc + group.save() + if delete_user_id is not None: + try: + delete_user_id = int(delete_user_id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + delete_user = GroupMembersModel.objects.filter(group_id=id, user_id=delete_user_id) + if not delete_user.exists(): + context['err_code'] = 4004 + context['error'] = "用户不存在或不在您的组织" + return Response(context) + delete_user.delete() + return Response(context) + + def delete(self, request): + context = dict() + context['err_code'] = 0 + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + data = QueryDict(request.body) + id = data.get('id') + if id is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + group = GroupModel.objects.filter(id=id) + if not group.exists(): + context['err_code'] = 4004 + context['error'] = "该小组不存在" + return Response(context) + group = group.first() + if user != group.owner: + context['err_code'] = 4003 + context['error'] = "没有权限执行该操作" + return Response(context) + group.delete() + return Response(context) + + +class MyGroupView(APIView): + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) + + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + status = data.get('status') + try: + start = int(data.get('start')) - 1 + end = int(data.get('end')) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + if status is None or start is None or end is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + if status == "member": + groups = GroupMembersModel.objects.order_by('-time').filter(user=user)[start:end] + context['data'] = GroupsSerializer(groups, many=True).data + elif status == "owner": + groups = GroupModel.objects.order_by('-create_time').filter(owner=user)[start:end] + context['data'] = CreateGroupsSerializer(groups, many=True).data + else: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + return Response(context) + + def post(self, request): + context = dict() + context['err_code'] = 0 + data = request.POST + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + id = data.get('id') + password = data.get('password') + if id is None or password is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + group = GroupModel.objects.filter(id=id) + if not group.exists(): + context['err_code'] = 4004 + context['error'] = "该小组不存在" + return Response(context) + group = group.first() + if GroupMembersModel.objects.filter(user=user, group=group).exists(): + context['err_code'] = 4003 + context['error'] = "您已经加入该小组" + return Response(context) + if group.owner == user: + context['err_code'] = 4003 + context['error'] = "不能加入自己创建的小组" + return Response(context) + if group.password != password: + context['err_code'] = 4002 + context['error'] = "密码错误" + return Response(context) + GroupMembersModel.objects.create(user=user, group=group) + return Response(context) + + +class MyGroupNumView(APIView): + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + status = data.get('status') + if status is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + if status == "member": + context['data'] = GroupMembersModel.objects.order_by('-time').filter(user=user).count() + elif status == "owner": + context['data'] = GroupModel.objects.order_by('-create_time').count() + else: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + return Response(context) diff --git a/login/serializers.py b/login/serializers.py index 26b64ee..a25935e 100644 --- a/login/serializers.py +++ b/login/serializers.py @@ -9,7 +9,7 @@ class LoginSerializer(serializers.Serializer): # 用于登录的表单合法性 remember = serializers.BooleanField() def validate_username(self, username): - if re.match("^[0-9]{9,9}$", username) is None: + if re.match("^[a-zA-Z0-9]{5,15}$", username) is None: raise serializers.ValidationError("用户名不符合规定") else: return username @@ -20,6 +20,28 @@ class LoginSerializer(serializers.Serializer): # 用于登录的表单合法性 else: return password +class RegisterSerializer(serializers.Serializer): # 用于注册的表单合法性验证,防止绕过前端验证 + username = serializers.CharField() + password = serializers.CharField() + nickname = serializers.CharField() + + def validate_username(self, username): + if re.match('^[a-zA-Z0-9]{5,15}$', username) is None: + raise serializers.ValidationError("学号不符合规定") + else: + return username + + def validate_password(self, password): + if len(password) != 32: + raise serializers.ValidationError("密码长度不正确") + else: + return password + + def validate_nickname(self, nickname): + if re.match("^[\u4e00-\u9fa5·]{2,18}$", nickname) is None: + raise serializers.ValidationError("姓名不符合规定") + else: + return nickname class UserSerializer(serializers.ModelSerializer): # 用于获取用户信息,反馈给用户 name = serializers.SerializerMethodField() diff --git a/login/views.py b/login/views.py index b2805f8..9a187f8 100644 --- a/login/views.py +++ b/login/views.py @@ -1,9 +1,10 @@ from django.contrib import auth -from .serializers import LoginSerializer,UserSerializer +from .serializers import LoginSerializer,UserSerializer,RegisterSerializer +from django.contrib.auth.models import User from rest_framework.views import APIView from rest_framework.response import Response import logging -from rest_framework.authentication import SessionAuthentication +from rest_framework.authentication import SessionAuthentication,BasicAuthentication from common.common import get_first_error @@ -64,7 +65,50 @@ class LogOutView(APIView): # 登出 context['data'] = dict() context['data']['result'] = True return Response(context) +class RegisterView(APIView): # 注册相关视图类 + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) + def post(self, request): + context = dict() + context['err_code']=0 + data = RegisterSerializer(data=request.POST) + if not data.is_valid(): # 验证数据的有效性,如果无效证明绕过了前端 + context['err_code'] = 4002 + errors = data.errors + key, value = get_first_error(errors) + context['error'] = value[0] + return Response(context) + data = data.data + username = data['username'] + password = data['password'] + nickname = data['nickname'] + if User.objects.filter(username=username).exists(): + context['error'] = "用户名已存在" + context['err_code'] = 4002 + return Response(context) + User.objects.create_user(username=username, password=password, first_name=nickname) + context['err_code'] = 0 + context['data']=dict() + context['data']['result']=True + return Response(context) + # def put(self,request): + # context = dict() + # context['err_code'] = 0 + # user=request.user + # if user.is_anonymous: + # context['err_code'] = 1001 + # context['error'] = "您还未登录" + # return Response(context) + # data = QueryDict(request.body) + # nickname = data.get("nickname") + # if nickname is None or re.match("^[\u4e00-\u9fa5·]{2,25}$", nickname) is None: + # context['err_code'] = 4002 + # context['error']="数据不合法" + # return Response(context) + # user_model=User.objects.get(username=user.username) + # user_model.first_name=nickname + # user_model.save() + # return Response(context) class MeView(APIView): def get(self, request): diff --git a/work/models.py b/work/models.py index 9267b27..12b9f04 100644 --- a/work/models.py +++ b/work/models.py @@ -39,3 +39,5 @@ class DoneModel(models.Model): work = models.ForeignKey(to=HomeWorkInfModel, verbose_name="作业", on_delete=models.CASCADE, related_name='done') owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Done", verbose_name="创建人") create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") # 创建的时间 + + -- Gitee From 1832d1630efc2e5baddd76c2bd41ae761ed65130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 9 Nov 2020 21:34:33 +0800 Subject: [PATCH 11/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E3=80=81=E6=9F=A5=E7=9C=8B=E3=80=81=E5=88=A0=E9=99=A4=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/urls.py | 2 +- group/models.py | 2 +- group/serializers.py | 21 ++++++------ group/views.py | 80 ++++++++++++++------------------------------ work/views.py | 8 ++--- 5 files changed, 42 insertions(+), 71 deletions(-) diff --git a/HomeWork/urls.py b/HomeWork/urls.py index a69c3c9..16f602d 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -29,6 +29,6 @@ urlpatterns = [ path('submit/',SubmitView.as_view(),), path('group/',GroupView.as_view()), path('mygroup/',MyGroupView.as_view()), - path('mygroupnum',MyGroupNumView.as_view()), + path('mygroupnum/',MyGroupNumView.as_view()), path('register/',RegisterView.as_view()), ] diff --git a/group/models.py b/group/models.py index 3eb1f25..17b18c1 100644 --- a/group/models.py +++ b/group/models.py @@ -20,7 +20,7 @@ class GroupModel(models.Model): def __str__(self): return str(self.name) - def get_all_members(self): + def get_members(self): yield self.owner join_groups = GroupMembersModel.objects.filter(group=self) for member in join_groups: diff --git a/group/serializers.py b/group/serializers.py index ff0a1cc..5bc3ede 100644 --- a/group/serializers.py +++ b/group/serializers.py @@ -5,7 +5,7 @@ import re class GroupSerializer(serializers.ModelSerializer): members = serializers.SerializerMethodField() - + owner = serializers.SerializerMethodField() class Meta: model = GroupModel fields = ['id', 'name', 'desc', 'create_time', 'owner', 'members', 'password'] @@ -16,11 +16,13 @@ class GroupSerializer(serializers.ModelSerializer): for member in members: members_list.append({'id':member.id,'name':member.first_name}) return members_list + def get_owner(self,obj): + return obj.owner.first_name class GroupUnSerializer(serializers.Serializer): name = serializers.CharField() - desc = serializers.CharField() + desc = serializers.CharField(required=False,default="") password = serializers.CharField() def validate_name(self, name): @@ -46,9 +48,9 @@ def valid_group_information(name, data): if name == 'name': return re.match("^[a-zA-Z0-9\u4e00-\u9fa5_丶]{1,20}$", data) is not None if name == 'desc': - return re.match("^[a-zA-Z0-9\u4e00-\u9fa5_丶]{5,200}$", data) is not None + return re.match("^[a-zA-Z0-9\u4e00-\u9fa5_丶]{0,200}$", data) is not None if name == 'password': - return re.match("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$", data) is not None + return re.match("^[0-9a-zA-Z]{6,18}$", data) is not None class GroupsSerializer(serializers.Serializer): @@ -63,10 +65,7 @@ class GroupsSerializer(serializers.Serializer): return obj.group.name -class CreateGroupsSerializer(serializers.Serializer): - id = serializers.IntegerField() - time = serializers.SerializerMethodField() - name = serializers.CharField() - - def get_time(self, obj): - return obj.create_time +class CreateGroupsSerializer(serializers.ModelSerializer): + class Meta: + model = GroupModel + fields = ['id', 'name', 'create_time','owner'] diff --git a/group/views.py b/group/views.py index 8d221d6..8616568 100644 --- a/group/views.py +++ b/group/views.py @@ -39,14 +39,14 @@ class GroupView(APIView): return Response(context) query = GroupModel.objects.filter(id=id) if not query.exists(): # 请求数据不存在 - context['err_code'] = 3004 + context['err_code'] = 4004 context['error'] = "无法找到您要的数据" return Response(context) group = query.first() is_member = GroupMembersModel.objects.filter(user=user, group=group).exists() is_owner = (group.owner == user) if not is_member and not is_owner: - context['err_code'] = 3003 + context['err_code'] = 4003 context['error'] = "您无权查看此内容" return Response(context) context['data'] = GroupSerializer(group).data @@ -72,22 +72,33 @@ class GroupView(APIView): context['err_code'] = 2002 return Response(context) data = data.data - GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password']) + group=GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password']) + context['data']=dict() + context['data']['id']=group.id return Response(context) def put(self, request): context = dict() context['err_code'] = 0 user = request.user + put_data = QueryDict(request.body) if user.is_anonymous: context['err_code'] = 1001 context['error'] = "您还未登录" return Response(context) - data = QueryDict(request.body) - id = data.get('id') + data = GroupUnSerializer(data=put_data) + if not data.is_valid(): # 验证有效性 + errors = data.errors + key, value = get_first_error(errors) + context['error'] = value[0] + context['err_code'] = 2002 + return Response(context) + data = data.data + + id= put_data.get('id') if id is None: - context['err_code'] = 2001 - context['error'] = "请求参数不正确" + context['error'] = "没有请求的id" + context['err_code'] = 2002 return Response(context) try: id = int(id) @@ -95,56 +106,17 @@ class GroupView(APIView): context['err_code'] = 2002 context['error'] = "参数格式不正确" return Response(context) - password = data.get('password') - name = data.get('name') - desc = data.get('desc') - delete_user_id = data.get('delete_user_id') - if password is None and name is None and desc is None and delete_user_id is None: - context['err_code'] = 2001 - context['error'] = "请求参数不正确" - return Response(context) - group = GroupModel.objects.filter(id=id) - if not group.exists(): + querys = GroupModel.objects.filter(id=id) + if not querys.exists(): # 请求数据不存在 context['err_code'] = 4004 - context['error'] = "该小组不存在" + context['error'] = "无法找到您要的数据" return Response(context) - group = group.first() - if user != group.owner: + query = querys.first() + if user != query.owner: context['err_code'] = 4003 - context['error'] = "您无权操作" - return Response(context) - if password is not None: - if not valid_group_information('password', password): - context['err_code'] = 2002 - context['error'] = "格式不正确" - return Response(context) - group.password = password - if name is not None: - if not valid_group_information('name', name): - context['err_code'] = 2002 - context['error'] = "格式不正确" - return Response(context) - group.name = name - if desc is not None: - if not valid_group_information('desc', desc): - context['err_code'] = 2002 - context['error'] = "格式不正确" - return Response(context) - group.desc = desc - group.save() - if delete_user_id is not None: - try: - delete_user_id = int(delete_user_id) - except: - context['err_code'] = 2002 - context['error'] = "参数格式不正确" - return Response(context) - delete_user = GroupMembersModel.objects.filter(group_id=id, user_id=delete_user_id) - if not delete_user.exists(): - context['err_code'] = 4004 - context['error'] = "用户不存在或不在您的组织" - return Response(context) - delete_user.delete() + context['error'] = "您无权执行此操作" + return Response(context) + querys.update(name=data['name'],desc=data['desc'],password=data['password']) return Response(context) def delete(self, request): diff --git a/work/views.py b/work/views.py index ca0d261..33296d9 100644 --- a/work/views.py +++ b/work/views.py @@ -119,17 +119,17 @@ class HomeWorkView(APIView): context['err_code'] = 2002 context['error'] = "参数格式不正确" return Response(context) - query = HomeWorkInfModel.objects.filter(id=id) - if not query.exists(): # 请求数据不存在 + querys = HomeWorkInfModel.objects.filter(id=id) + if not querys.exists(): # 请求数据不存在 context['err_code'] = 4004 context['error'] = "无法找到您要的数据" return Response(context) - query = query.first() + query = querys.first() if user != query.owner: context['err_code'] = 4003 context['error'] = "您无权执行此操作" return Response(context) - HomeWorkInfModel.objects.update(name=data['name'], + querys.update(name=data['name'], type=data['type'], subject=data['subject'], remark=data.get('remark') if data.get('remark') else '', -- Gitee From 057b37fcb61f6e08044edc9f8d122845e0db9817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 9 Nov 2020 22:59:31 +0800 Subject: [PATCH 12/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=88=90=E5=91=98?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/urls.py | 3 +- group/serializers.py | 34 ++++++++++++------ group/views.py | 86 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 104 insertions(+), 19 deletions(-) diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 16f602d..0799e1d 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -17,7 +17,7 @@ from django.contrib import admin from django.urls import path from login.views import LoginView,LogOutView,MeView,RegisterView from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView -from group.views import GroupView,MyGroupNumView,MyGroupView +from group.views import GroupView,MyGroupNumView,MyGroupView,GroupMembersView urlpatterns = [ path('admin/', admin.site.urls), path('login/',LoginView.as_view()), @@ -31,4 +31,5 @@ urlpatterns = [ path('mygroup/',MyGroupView.as_view()), path('mygroupnum/',MyGroupNumView.as_view()), path('register/',RegisterView.as_view()), + path('groupmembers/',GroupMembersView.as_view()) ] diff --git a/group/serializers.py b/group/serializers.py index 5bc3ede..c4a721a 100644 --- a/group/serializers.py +++ b/group/serializers.py @@ -4,25 +4,19 @@ import re class GroupSerializer(serializers.ModelSerializer): - members = serializers.SerializerMethodField() owner = serializers.SerializerMethodField() + class Meta: model = GroupModel fields = ['id', 'name', 'desc', 'create_time', 'owner', 'members', 'password'] - def get_members(self, obj): - members_list=list() - members=obj.get_members() - for member in members: - members_list.append({'id':member.id,'name':member.first_name}) - return members_list - def get_owner(self,obj): + def get_owner(self, obj): return obj.owner.first_name class GroupUnSerializer(serializers.Serializer): name = serializers.CharField() - desc = serializers.CharField(required=False,default="") + desc = serializers.CharField(required=False, default="") password = serializers.CharField() def validate_name(self, name): @@ -55,8 +49,9 @@ def valid_group_information(name, data): class GroupsSerializer(serializers.Serializer): id = serializers.SerializerMethodField() - time = serializers.DateTimeField() + time = serializers.SerializerMethodField() name = serializers.SerializerMethodField() + owner = serializers.SerializerMethodField() def get_id(self, obj): return obj.group.id @@ -64,8 +59,25 @@ class GroupsSerializer(serializers.Serializer): def get_name(self, obj): return obj.group.name + def get_time(self, obj): + return obj.time + + def get_owner(self, obj): + return obj.group.owner.first_name + class CreateGroupsSerializer(serializers.ModelSerializer): class Meta: model = GroupModel - fields = ['id', 'name', 'create_time','owner'] + fields = ['id', 'name', 'create_time'] + + +class GroupMembersSerializer(serializers.Serializer): + members = serializers.SerializerMethodField() + + def get_members(self, obj): + members_list = list() + members = obj.get_members() + for member in members: + members_list.append({'id': member.id, 'name': member.first_name,'username':member.username}) + return members_list diff --git a/group/views.py b/group/views.py index 8616568..17695b2 100644 --- a/group/views.py +++ b/group/views.py @@ -1,6 +1,6 @@ from rest_framework.views import APIView, Response from .serializers import GroupSerializer, GroupsSerializer, CreateGroupsSerializer, GroupUnSerializer, \ - valid_group_information + GroupMembersSerializer from .models import GroupModel, GroupMembersModel from common.common import get_first_error from rest_framework.authentication import SessionAuthentication, BasicAuthentication @@ -14,7 +14,6 @@ class CsrfExemptSessionAuthentication(SessionAuthentication): class GroupView(APIView): - authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) def get(self, request): @@ -72,9 +71,9 @@ class GroupView(APIView): context['err_code'] = 2002 return Response(context) data = data.data - group=GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password']) - context['data']=dict() - context['data']['id']=group.id + group = GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password']) + context['data'] = dict() + context['data']['id'] = group.id return Response(context) def put(self, request): @@ -95,7 +94,7 @@ class GroupView(APIView): return Response(context) data = data.data - id= put_data.get('id') + id = put_data.get('id') if id is None: context['error'] = "没有请求的id" context['err_code'] = 2002 @@ -116,7 +115,7 @@ class GroupView(APIView): context['err_code'] = 4003 context['error'] = "您无权执行此操作" return Response(context) - querys.update(name=data['name'],desc=data['desc'],password=data['password']) + querys.update(name=data['name'], desc=data['desc'], password=data['password']) return Response(context) def delete(self, request): @@ -153,6 +152,79 @@ class GroupView(APIView): return Response(context) +class GroupMembersView(APIView): + authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) + + def get(self, request): + context = dict() + context['err_code'] = 0 + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + data = request.GET + id = data.get('id') + if id is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + try: + id = int(id) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + group = GroupModel.objects.filter(id=id) + if not group.exists(): + context['err_code'] = 4004 + context['error'] = "该小组不存在" + return Response(context) + group = group.first() + if user != group.owner: + context['err_code'] = 4003 + context['error'] = "没有权限执行该操作" + return Response(context) + context['data'] = GroupMembersSerializer(group).data['members'] + return Response(context) + + def delete(self, request): + context = dict() + context['err_code'] = 0 + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + data = QueryDict(request.body) + gid = data.get('group_id') + uid = data.get('user_id') + if gid is None or uid is None: + context['err_code'] = 2001 + context['error'] = "请求参数不正确" + return Response(context) + try: + uid = int(uid) + gid = int(gid) + except: + context['err_code'] = 2002 + context['error'] = "参数格式不正确" + return Response(context) + member=GroupMembersModel.objects.filter(user__id=uid,group__id=gid) + group = GroupModel.objects.filter(id=gid) + if not member.exists() or not group.exists(): + context['err_code'] = 4004 + context['error'] = "该成员不在您的小组" + return Response(context) + member = member.first() + group=group.first() + if user != group.owner: + context['err_code'] = 4003 + context['error'] = "没有权限执行该操作" + return Response(context) + member.delete() + return Response(context) + class MyGroupView(APIView): authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication) -- Gitee From e70e590ed3ac83b0c152469b501bec3ffe94ae6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Tue, 10 Nov 2020 23:25:34 +0800 Subject: [PATCH 13/24] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=92=8C=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E5=B0=8F=E7=BB=84=E6=97=B6=E5=8F=AF=E4=BB=A5=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=88=90=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group/admin.py | 3 +-- group/models.py | 11 ----------- work/models.py | 3 ++- work/serializers.py | 12 ++++++++++-- work/views.py | 24 +++++++++++++++++++++++- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/group/admin.py b/group/admin.py index bfa3fca..5f69dc7 100644 --- a/group/admin.py +++ b/group/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import GroupModel, GroupMembersModel, WorkGroupModel +from .models import GroupModel, GroupMembersModel # Register your models here. @@ -22,4 +22,3 @@ class WorkGroupAdmin(admin.ModelAdmin): admin.site.register(GroupModel, GroupAdmin) admin.site.register(GroupMembersModel, GroupMembersAdmin) -admin.site.register(WorkGroupModel, WorkGroupAdmin) diff --git a/group/models.py b/group/models.py index 17b18c1..f342802 100644 --- a/group/models.py +++ b/group/models.py @@ -1,6 +1,5 @@ from django.db import models from django.contrib.auth.models import User -from work.models import HomeWorkInfModel # Create your models here. @@ -40,13 +39,3 @@ class GroupMembersModel(models.Model): def __str__(self): return "{}-{}".format(self.group,self.user.first_name) - - -class WorkGroupModel(models.Model): - class Meta: - db_table = "homeworkgroup" - verbose_name = "作业小组" - verbose_name_plural = verbose_name - - group = models.ForeignKey(GroupModel, on_delete=models.CASCADE, verbose_name="小组", related_name="work") - work = models.ForeignKey(HomeWorkInfModel, on_delete=models.CASCADE, verbose_name="作业", related_name="groups") diff --git a/work/models.py b/work/models.py index 12b9f04..e3b628f 100644 --- a/work/models.py +++ b/work/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.auth.models import User import datetime +from group.models import GroupModel # Create your models here. @@ -25,7 +26,7 @@ class HomeWorkInfModel(models.Model): default=False) member_can_see_others = models.BooleanField(verbose_name="成员可互相查看作业", choices=((False, "否"), (True, "是")), default=False) - + groups=models.ManyToManyField(to=GroupModel,related_name="work",verbose_name="参与组") class DoneModel(models.Model): class Meta: diff --git a/work/serializers.py b/work/serializers.py index 3509234..5f31cc7 100644 --- a/work/serializers.py +++ b/work/serializers.py @@ -10,7 +10,6 @@ class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法 end_time = serializers.CharField() member_can_know_donelist = serializers.CharField() member_can_see_others = serializers.CharField() - def validate_name(self, name): if len(name) > 50: raise serializers.ValidationError("名称长度过长") @@ -46,7 +45,7 @@ class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法 class HomeWorkInfSerializer(serializers.ModelSerializer): owner = serializers.SerializerMethodField() - + groups=serializers.SerializerMethodField() class Meta: model = HomeWorkInfModel fields = '__all__' @@ -54,6 +53,15 @@ class HomeWorkInfSerializer(serializers.ModelSerializer): def get_owner(self, obj): return obj.owner.first_name + def get_groups(self,obj): + groups_query = obj.groups.all() + groups_list = list() + for group in groups_query: + group_inf = dict() + group_inf['id'] = group.id + group_inf['name'] = group.name + groups_list.append(group_inf) + return groups_list class HomeWorkAllSerializer(serializers.ModelSerializer): class Meta: diff --git a/work/views.py b/work/views.py index 33296d9..c942cba 100644 --- a/work/views.py +++ b/work/views.py @@ -36,6 +36,23 @@ class HomeWorkView(APIView): context['err_code'] = 0 data = data.data end_time = data['end_time'] + groups = request.POST.get('groups') + if groups is None or len(groups)==0: + context['error'] = "至少选择一个小组" + context['err_code'] = 2002 + return Response(context) + groups=str(groups) + groups=groups.split(',') + groups_in=list() + try: + for group in groups: + group=int(group) + groups_in.append(group) + except: + context['error'] = "小组id只能为int" + context['err_code'] = 2002 + return Response(context) + homework = HomeWorkInfModel.objects.create(name=data['name'], type=data['type'], subject=data['subject'], @@ -50,8 +67,12 @@ class HomeWorkView(APIView): day=int(end_time[8:10]), hour=int(end_time[11:13]), minute=int(end_time[14:16]) - ) + ), + ) + + for group_id in groups: + homework.groups.add(group_id) context['data'] = dict() context['data']['id'] = homework.id return Response(context) @@ -87,6 +108,7 @@ class HomeWorkView(APIView): context['data'].update({'is_creater': True}) else: context['data'].update({'is_creater': False}) + return Response(context) def put(self, request): -- Gitee From 15b271beeb56b9e1e4e6315f1cebae1ca7a746a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Wed, 11 Nov 2020 21:12:39 +0800 Subject: [PATCH 14/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E8=87=AA=E5=B7=B1=E5=8F=82=E4=B8=8E=E7=9A=84=E5=92=8C=E6=9C=AA?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BD=9C=E4=B8=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work/admin.py | 9 +++++---- work/models.py | 17 ++++++++++------- work/serializers.py | 38 ++++++++++++++++++++++++++------------ work/views.py | 19 ++++++++++++------- 4 files changed, 53 insertions(+), 30 deletions(-) diff --git a/work/admin.py b/work/admin.py index a72f927..32fb724 100644 --- a/work/admin.py +++ b/work/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import HomeWorkInfModel, DoneModel +from .models import HomeWorkInfModel, HomeWorkMembersModel # Register your models here. @@ -12,9 +12,10 @@ class HomeWorkAdmin(admin.ModelAdmin): list_filter = ['owner', 'subject'] -class DoneAdmin(admin.ModelAdmin): - list_display = ['work'] +class HomeWorkMembersAdmin(admin.ModelAdmin): + list_display = ['work','owner','done'] + list_display_links =['work','owner'] admin.site.register(HomeWorkInfModel, HomeWorkAdmin) -admin.site.register(DoneModel, DoneAdmin) +admin.site.register(HomeWorkMembersModel, HomeWorkMembersAdmin) diff --git a/work/models.py b/work/models.py index e3b628f..8c1ae4a 100644 --- a/work/models.py +++ b/work/models.py @@ -3,7 +3,6 @@ from django.contrib.auth.models import User import datetime from group.models import GroupModel - # Create your models here. class HomeWorkInfModel(models.Model): class Meta: @@ -26,19 +25,23 @@ class HomeWorkInfModel(models.Model): default=False) member_can_see_others = models.BooleanField(verbose_name="成员可互相查看作业", choices=((False, "否"), (True, "是")), default=False) - groups=models.ManyToManyField(to=GroupModel,related_name="work",verbose_name="参与组") + groups = models.ManyToManyField(to=GroupModel, related_name="work", verbose_name="参与组") + + members = models.ManyToManyField(to=User,related_name='work',verbose_name='参与人员',through='HomeWorkMembersModel') + -class DoneModel(models.Model): + +class HomeWorkMembersModel(models.Model): class Meta: db_table = "done" verbose_name = "作业完成情况" verbose_name_plural = verbose_name def __str__(self): - return self.work + return "{}-{}".format(self.work, self.owner) work = models.ForeignKey(to=HomeWorkInfModel, verbose_name="作业", on_delete=models.CASCADE, related_name='done') - owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Done", verbose_name="创建人") - create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") # 创建的时间 - + owner = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name="Done", verbose_name="参与人") + done = models.BooleanField(verbose_name="已完成", db_index=True, default=False) + end_time = models.DateTimeField(auto_now=True, verbose_name="截止时间") # 创建的时间 \ No newline at end of file diff --git a/work/serializers.py b/work/serializers.py index 5f31cc7..9a9901a 100644 --- a/work/serializers.py +++ b/work/serializers.py @@ -2,7 +2,7 @@ from rest_framework import serializers from .models import HomeWorkInfModel -class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法性验证,防止绕过前端验证 +class HomeWorkUpSerializer(serializers.Serializer): # 用于登录的表单合法性验证,防止绕过前端验证 name = serializers.CharField() type = serializers.CharField() subject = serializers.CharField() @@ -10,6 +10,7 @@ class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法 end_time = serializers.CharField() member_can_know_donelist = serializers.CharField() member_can_see_others = serializers.CharField() + def validate_name(self, name): if len(name) > 50: raise serializers.ValidationError("名称长度过长") @@ -45,7 +46,8 @@ class HomeWorkSerializer(serializers.Serializer): # 用于登录的表单合法 class HomeWorkInfSerializer(serializers.ModelSerializer): owner = serializers.SerializerMethodField() - groups=serializers.SerializerMethodField() + groups = serializers.SerializerMethodField() + class Meta: model = HomeWorkInfModel fields = '__all__' @@ -53,7 +55,7 @@ class HomeWorkInfSerializer(serializers.ModelSerializer): def get_owner(self, obj): return obj.owner.first_name - def get_groups(self,obj): + def get_groups(self, obj): groups_query = obj.groups.all() groups_list = list() for group in groups_query: @@ -63,10 +65,12 @@ class HomeWorkInfSerializer(serializers.ModelSerializer): groups_list.append(group_inf) return groups_list -class HomeWorkAllSerializer(serializers.ModelSerializer): + + +class HomeWorkCreateSerializer(serializers.ModelSerializer): class Meta: model = HomeWorkInfModel - fields = ['id','name', 'end_time', 'owner','subject','end_time'] + fields = ['id', 'name', 'end_time', 'owner', 'subject', 'end_time'] owner = serializers.SerializerMethodField() @@ -74,12 +78,22 @@ class HomeWorkAllSerializer(serializers.ModelSerializer): return obj.owner.first_name -class HomeWorkCreateSerializer(serializers.ModelSerializer): - class Meta: - model = HomeWorkInfModel - fields = ['id','name', 'end_time', 'owner','subject','end_time'] - +class HomeWorkSerializer(serializers.Serializer): + id = serializers.SerializerMethodField() + name = serializers.SerializerMethodField() owner = serializers.SerializerMethodField() + subject = serializers.SerializerMethodField() + end_time = serializers.DateTimeField() + done = serializers.BooleanField() - def get_owner(self, obj): - return obj.owner.first_name + def get_id(self,obj): + return obj.work.id + + def get_name(self,obj): + return obj.work.name + + def get_owner(self,obj): + return obj.work.owner.first_name + + def get_subject(self,obj): + return obj.work.subject diff --git a/work/views.py b/work/views.py index c942cba..647e095 100644 --- a/work/views.py +++ b/work/views.py @@ -1,8 +1,8 @@ from rest_framework.views import APIView from rest_framework.response import Response -from .serializers import HomeWorkSerializer, HomeWorkInfSerializer, HomeWorkAllSerializer, HomeWorkCreateSerializer +from .serializers import HomeWorkUpSerializer, HomeWorkInfSerializer, HomeWorkSerializer, HomeWorkCreateSerializer from common.common import get_first_error -from .models import HomeWorkInfModel +from .models import HomeWorkInfModel,HomeWorkMembersModel from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication from django.http import QueryDict @@ -25,7 +25,7 @@ class HomeWorkView(APIView): context['err_code'] = 1001 context['error'] = "您还未登录" return Response(context) - data = HomeWorkSerializer(data=request.POST) + data = HomeWorkUpSerializer(data=request.POST) if not data.is_valid(): # 验证有效性 errors = data.errors key, value = get_first_error(errors) @@ -119,7 +119,7 @@ class HomeWorkView(APIView): context['error'] = "您还未登录" return Response(context) put_data = QueryDict(request.body) - data = HomeWorkSerializer(data=put_data) + data = HomeWorkUpSerializer(data=put_data) if not data.is_valid(): # 验证有效性 errors = data.errors key, value = get_first_error(errors) @@ -220,7 +220,9 @@ class MyHomeWorkNumView(APIView): context['error'] = "请求参数不正确" return Response(context) if status == "member": - context['data'] = HomeWorkInfModel.objects.filter().count() + context['data'] = user.work.count() + elif status=='notdone': + context['data'] = user.work.filter(done=False).count() elif status == "owner": context['data'] = HomeWorkInfModel.objects.filter(owner=user).count() else: @@ -255,8 +257,11 @@ class MyHomeWorkView(APIView): context['error'] = "请求参数不正确" return Response(context) if status == "member": - work = HomeWorkInfModel.objects.order_by('-end_time').filter()[start:end] - context['data'] = HomeWorkAllSerializer(work, many=True).data + work = HomeWorkMembersModel.objects.filter(owner=user).order_by('-end_time') + context['data'] = HomeWorkSerializer(work, many=True).data + elif status=="notdone": + work = HomeWorkMembersModel.objects.filter(owner=user,done=False).order_by('-end_time') + context['data'] = HomeWorkSerializer(work, many=True).data elif status == "owner": work = HomeWorkInfModel.objects.order_by('-end_time').filter(owner=user)[start:end] context['data'] = HomeWorkCreateSerializer(work, many=True).data -- Gitee From c7d50f55954131dd9a9fb2c09629f823e91c72af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Wed, 11 Nov 2020 21:59:51 +0800 Subject: [PATCH 15/24] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E7=9A=84bug=EF=BC=8C=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=88=97=E8=A1=A8=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=88=AA?= =?UTF-8?q?=E6=AD=A2=E6=97=B6=E9=97=B4=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= =?UTF-8?q?HomeWorkMembers=E8=A1=A8=E7=9A=84=E6=88=AA=E6=AD=A2=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work/models.py | 26 ++++++++++++++++--- work/views.py | 70 +++++++++++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/work/models.py b/work/models.py index 8c1ae4a..22b231c 100644 --- a/work/models.py +++ b/work/models.py @@ -2,6 +2,11 @@ from django.db import models from django.contrib.auth.models import User import datetime from group.models import GroupModel +from django.db.models.signals import m2m_changed, pre_save +import logging + +logger = logging.getLogger(__name__) + # Create your models here. class HomeWorkInfModel(models.Model): @@ -27,8 +32,7 @@ class HomeWorkInfModel(models.Model): default=False) groups = models.ManyToManyField(to=GroupModel, related_name="work", verbose_name="参与组") - members = models.ManyToManyField(to=User,related_name='work',verbose_name='参与人员',through='HomeWorkMembersModel') - + members = models.ManyToManyField(to=User, related_name='work', verbose_name='参与人员', through='HomeWorkMembersModel') class HomeWorkMembersModel(models.Model): @@ -44,4 +48,20 @@ class HomeWorkMembersModel(models.Model): owner = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name="Done", verbose_name="参与人") done = models.BooleanField(verbose_name="已完成", db_index=True, default=False) - end_time = models.DateTimeField(auto_now=True, verbose_name="截止时间") # 创建的时间 \ No newline at end of file + end_time = models.DateTimeField(verbose_name="截止时间") # 创建的时间 + + +def create_homework_members(sender, instance, **kwargs): + for group in instance.groups.all(): + for member in group.get_members(): + HomeWorkMembersModel.objects.update_or_create(defaults={'end_time': instance.end_time}, work=instance, + owner=member) + + +def change_end_time(sender, instance, **kwargs): + logger.critical("触发一次次改截止时间") + HomeWorkMembersModel.objects.filter(work=instance).update(end_time=instance.end_time) + + +m2m_changed.connect(create_homework_members, sender=HomeWorkInfModel.groups.through) +pre_save.connect(change_end_time, sender=HomeWorkInfModel) diff --git a/work/views.py b/work/views.py index 647e095..acd0544 100644 --- a/work/views.py +++ b/work/views.py @@ -2,7 +2,7 @@ from rest_framework.views import APIView from rest_framework.response import Response from .serializers import HomeWorkUpSerializer, HomeWorkInfSerializer, HomeWorkSerializer, HomeWorkCreateSerializer from common.common import get_first_error -from .models import HomeWorkInfModel,HomeWorkMembersModel +from .models import HomeWorkInfModel, HomeWorkMembersModel from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication from django.http import QueryDict @@ -37,16 +37,16 @@ class HomeWorkView(APIView): data = data.data end_time = data['end_time'] groups = request.POST.get('groups') - if groups is None or len(groups)==0: + if groups is None or len(groups) == 0: context['error'] = "至少选择一个小组" context['err_code'] = 2002 return Response(context) - groups=str(groups) - groups=groups.split(',') - groups_in=list() + groups = str(groups) + groups = groups.split(',') + groups_in = list() try: for group in groups: - group=int(group) + group = int(group) groups_in.append(group) except: context['error'] = "小组id只能为int" @@ -70,7 +70,6 @@ class HomeWorkView(APIView): ), ) - for group_id in groups: homework.groups.add(group_id) context['data'] = dict() @@ -96,15 +95,22 @@ class HomeWorkView(APIView): context['err_code'] = 2002 context['error'] = "参数格式不正确" return Response(context) - query = HomeWorkInfModel.objects.filter(id=id) - if not query.exists(): # 请求数据不存在 + querys = HomeWorkInfModel.objects.filter(id=id) + if not querys.exists(): # 请求数据不存在 context['err_code'] = 4004 context['error'] = "无法找到您要的数据" return Response(context) - query = query.first() + query = querys.first() + is_member = HomeWorkMembersModel.objects.filter(owner=user, work__id=id).exists() + is_owner = (user == query.owner) + if not is_member and not is_owner: + context['err_code'] = 4003 + context['error'] = "您无权查看此内容" + return Response(context) + context['err_code'] = 0 context['data'] = HomeWorkInfSerializer(query).data - if user == query.owner: + if is_owner: context['data'].update({'is_creater': True}) else: context['data'].update({'is_creater': False}) @@ -152,21 +158,21 @@ class HomeWorkView(APIView): context['error'] = "您无权执行此操作" return Response(context) querys.update(name=data['name'], - type=data['type'], - subject=data['subject'], - remark=data.get('remark') if data.get('remark') else '', - owner=user, - member_can_know_donelist=True if data[ - 'member_can_know_donelist'] == 'true' else False, - member_can_see_others=True if data[ - 'member_can_see_others'] == 'true' else False, - end_time=datetime(year=int(end_time[0:4]), - month=int(end_time[5:7]), - day=int(end_time[8:10]), - hour=int(end_time[11:13]), - minute=int(end_time[14:16]) - ) - ) + type=data['type'], + subject=data['subject'], + remark=data.get('remark') if data.get('remark') else '', + owner=user, + member_can_know_donelist=True if data[ + 'member_can_know_donelist'] == 'true' else False, + member_can_see_others=True if data[ + 'member_can_see_others'] == 'true' else False, + ) + query.end_time = datetime(year=int(end_time[0:4]), + month=int(end_time[5:7]), + day=int(end_time[8:10]), + hour=int(end_time[11:13]), + minute=int(end_time[14:16])) + query.save() # 没有这一行不能触发自动修改事件 return Response(context) def delete(self, request): @@ -220,9 +226,9 @@ class MyHomeWorkNumView(APIView): context['error'] = "请求参数不正确" return Response(context) if status == "member": - context['data'] = user.work.count() - elif status=='notdone': - context['data'] = user.work.filter(done=False).count() + context['data'] = HomeWorkMembersModel.objects.filter(owner=user).count() + elif status == 'notdone': + context['data'] = HomeWorkMembersModel.objects.filter(owner=user, done=False).count() elif status == "owner": context['data'] = HomeWorkInfModel.objects.filter(owner=user).count() else: @@ -257,10 +263,10 @@ class MyHomeWorkView(APIView): context['error'] = "请求参数不正确" return Response(context) if status == "member": - work = HomeWorkMembersModel.objects.filter(owner=user).order_by('-end_time') + work = HomeWorkMembersModel.objects.filter(owner=user).order_by('-end_time')[start:end] context['data'] = HomeWorkSerializer(work, many=True).data - elif status=="notdone": - work = HomeWorkMembersModel.objects.filter(owner=user,done=False).order_by('-end_time') + elif status == "notdone": + work = HomeWorkMembersModel.objects.filter(owner=user, done=False).order_by('-end_time')[start:end] context['data'] = HomeWorkSerializer(work, many=True).data elif status == "owner": work = HomeWorkInfModel.objects.order_by('-end_time').filter(owner=user)[start:end] -- Gitee From 2a1446dd2dd9e1be01811a8e800d64ee63db80b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Wed, 11 Nov 2020 22:17:46 +0800 Subject: [PATCH 16/24] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=B0=8F=E7=BB=84?= =?UTF-8?q?=E4=BC=9A=E8=87=AA=E5=8A=A8=E5=90=8C=E6=AD=A5=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E7=9A=84=E4=BD=9C=E4=B8=9A=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=88=91?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E7=9A=84=E5=B0=8F=E7=BB=84=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group/models.py | 16 +++++++++++++++- group/views.py | 2 +- work/models.py | 3 +-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/group/models.py b/group/models.py index f342802..d24966b 100644 --- a/group/models.py +++ b/group/models.py @@ -1,5 +1,7 @@ from django.db import models from django.contrib.auth.models import User +from django.db.models.signals import post_save +from work.models import HomeWorkMembersModel # Create your models here. @@ -38,4 +40,16 @@ class GroupMembersModel(models.Model): time = models.DateTimeField(auto_now_add=True, verbose_name="加入时间") def __str__(self): - return "{}-{}".format(self.group,self.user.first_name) + return "{}-{}".format(self.group, self.user.first_name) + + +def create_homework_members(sender, instance, created, **kwargs): + if created: + group = instance.group + user = instance.user + works = group.work.all() + for work in works: + HomeWorkMembersModel.objects.update_or_create(owner=user, work=work,end_time=work.end_time) + + +post_save.connect(create_homework_members, sender=GroupMembersModel) diff --git a/group/views.py b/group/views.py index 17695b2..985a067 100644 --- a/group/views.py +++ b/group/views.py @@ -322,7 +322,7 @@ class MyGroupNumView(APIView): if status == "member": context['data'] = GroupMembersModel.objects.order_by('-time').filter(user=user).count() elif status == "owner": - context['data'] = GroupModel.objects.order_by('-create_time').count() + context['data'] = GroupModel.objects.order_by('-create_time').filter(owner=user).count() else: context['err_code'] = 2001 context['error'] = "请求参数不正确" diff --git a/work/models.py b/work/models.py index 22b231c..9c31e65 100644 --- a/work/models.py +++ b/work/models.py @@ -1,7 +1,6 @@ from django.db import models from django.contrib.auth.models import User import datetime -from group.models import GroupModel from django.db.models.signals import m2m_changed, pre_save import logging @@ -30,7 +29,7 @@ class HomeWorkInfModel(models.Model): default=False) member_can_see_others = models.BooleanField(verbose_name="成员可互相查看作业", choices=((False, "否"), (True, "是")), default=False) - groups = models.ManyToManyField(to=GroupModel, related_name="work", verbose_name="参与组") + groups = models.ManyToManyField(to='group.GroupModel', related_name="work", verbose_name="参与组") members = models.ManyToManyField(to=User, related_name='work', verbose_name='参与人员', through='HomeWorkMembersModel') -- Gitee From 4e819aefa8d82198eaf05a87ee0f814c7651b58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Wed, 11 Nov 2020 23:29:52 +0800 Subject: [PATCH 17/24] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=86=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=97=A0=E7=94=A8=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/group/views.py b/group/views.py index 985a067..e379661 100644 --- a/group/views.py +++ b/group/views.py @@ -320,9 +320,9 @@ class MyGroupNumView(APIView): context['error'] = "请求参数不正确" return Response(context) if status == "member": - context['data'] = GroupMembersModel.objects.order_by('-time').filter(user=user).count() + context['data'] = GroupMembersModel.objects.filter(user=user).count() elif status == "owner": - context['data'] = GroupModel.objects.order_by('-create_time').filter(owner=user).count() + context['data'] = GroupModel.objects.filter(owner=user).count() else: context['err_code'] = 2001 context['error'] = "请求参数不正确" -- Gitee From 30a1d1ac472b6291f6b1b95fd694ad4b43101bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Thu, 12 Nov 2020 22:27:33 +0800 Subject: [PATCH 18/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/settings.py | 7 +----- login/serializers.py | 2 +- work/models.py | 2 ++ work/views.py | 57 ++++++++++++++++++++++++++++++++++++++------ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/HomeWork/settings.py b/HomeWork/settings.py index d2b9c92..d2fe494 100644 --- a/HomeWork/settings.py +++ b/HomeWork/settings.py @@ -12,10 +12,10 @@ https://docs.djangoproject.com/en/3.1/ref/settings/ from pathlib import Path import os + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ @@ -27,7 +27,6 @@ DEBUG = True ALLOWED_HOSTS = ['*'] - # Application definition INSTALLED_APPS = [ @@ -74,7 +73,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'HomeWork.wsgi.application' - # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases @@ -85,7 +83,6 @@ DATABASES = { } } - # Password validation # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators @@ -104,7 +101,6 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] - # Internationalization # https://docs.djangoproject.com/en/3.1/topics/i18n/ @@ -118,7 +114,6 @@ USE_L10N = True USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.1/howto/static-files/ diff --git a/login/serializers.py b/login/serializers.py index a25935e..af68a2c 100644 --- a/login/serializers.py +++ b/login/serializers.py @@ -26,7 +26,7 @@ class RegisterSerializer(serializers.Serializer): # 用于注册的表单合法 nickname = serializers.CharField() def validate_username(self, username): - if re.match('^[a-zA-Z0-9]{5,15}$', username) is None: + if re.match('^[A-Z0-9]{5,15}$', username) is None: raise serializers.ValidationError("学号不符合规定") else: return username diff --git a/work/models.py b/work/models.py index 9c31e65..03c6d86 100644 --- a/work/models.py +++ b/work/models.py @@ -48,6 +48,8 @@ class HomeWorkMembersModel(models.Model): done = models.BooleanField(verbose_name="已完成", db_index=True, default=False) end_time = models.DateTimeField(verbose_name="截止时间") # 创建的时间 + upload_time = models.DateTimeField(verbose_name="提交时间",null=True) + file_name = models.CharField(max_length=100,verbose_name="保存文件名",default="") def create_homework_members(sender, instance, **kwargs): diff --git a/work/views.py b/work/views.py index acd0544..af08ba0 100644 --- a/work/views.py +++ b/work/views.py @@ -291,31 +291,74 @@ class SubmitView(APIView): context['error'] = "您还未登录" return Response(context) work_id = data.get('work_id') + print(work_id) try: work_id = int(work_id) except: context['err_code'] = 1002 context['error'] = "请求参数不正确" return Response(context) - work = HomeWorkInfModel.objects.filter(id=work_id) - if not work.exists(): + done = HomeWorkMembersModel.objects.filter(work__id=work_id, owner=user) + if not done.exists(): context['err_code'] = 4004 - context['error'] = "无法找到您提交的作业" + context['error'] = "您没有次参加本作业" return Response(context) - work = work.first() - + done = done.first() file = request.FILES.get("file") # 获取上传的文件,如果没有文件,则默认为None if not file: context['err_code'] = 2001 context['error'] = "没有文件" return Response(context) dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), - str(work.id) + work.name) + str(done.work.id)) + file_name = user.username + user.first_name + os.path.splitext(file.name)[1] if not os.path.exists(dir_path): os.makedirs(dir_path) - path = os.path.join(dir_path, user.username + user.first_name + os.path.splitext(file.name)[1]) + path = os.path.join(dir_path, file_name) + done.done = True + done.file_name = file_name + done.upload_time= datetime.now() + done.save() destination = open(path, 'wb+') for chunk in file.chunks(): destination.write(chunk) destination.close() return Response(context) + + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + work_id = data.get('work_id') + print(work_id) + try: + work_id = int(work_id) + except: + context['err_code'] = 1002 + context['error'] = "请求参数不正确" + return Response(context) + done = HomeWorkMembersModel.objects.filter(work__id=work_id, owner=user) + if not done.exists(): + context['err_code'] = 4004 + context['error'] = "您没有次参加本作业" + return Response(context) + done = done.first() + context['data']=dict() + context['data']['done']=done.done + context['data']['file_name']=done.file_name + context['data']['work_name']=done.work.name + return Response(context) + + +class ExportView(APIView): + def get(self, request): + pass + +class DownloadView(APIView): + def get(self,request): + pass -- Gitee From cbbd592c3bd62724bdb94f6ddb7004af643afa3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Fri, 13 Nov 2020 00:17:06 +0800 Subject: [PATCH 19/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E8=87=AA=E5=B7=B1=E6=8F=90=E4=BA=A4=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- HomeWork/urls.py | 6 +++-- work/views.py | 60 +++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 631d80f..5ab05f5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ venv *.sqlite3 .idea /*/migrations -*.pyc \ No newline at end of file +*.pyc +file \ No newline at end of file diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 0799e1d..32c6e8c 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -16,7 +16,7 @@ Including another URLconf from django.contrib import admin from django.urls import path from login.views import LoginView,LogOutView,MeView,RegisterView -from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView +from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView,DownloadView,ExportView from group.views import GroupView,MyGroupNumView,MyGroupView,GroupMembersView urlpatterns = [ path('admin/', admin.site.urls), @@ -31,5 +31,7 @@ urlpatterns = [ path('mygroup/',MyGroupView.as_view()), path('mygroupnum/',MyGroupNumView.as_view()), path('register/',RegisterView.as_view()), - path('groupmembers/',GroupMembersView.as_view()) + path('groupmembers/',GroupMembersView.as_view()), + path('download/',DownloadView.as_view()), + path('export/',ExportView.as_view(),) ] diff --git a/work/views.py b/work/views.py index af08ba0..7af0620 100644 --- a/work/views.py +++ b/work/views.py @@ -5,7 +5,7 @@ from common.common import get_first_error from .models import HomeWorkInfModel, HomeWorkMembersModel from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication -from django.http import QueryDict +from django.http import QueryDict, FileResponse import os @@ -315,9 +315,13 @@ class SubmitView(APIView): if not os.path.exists(dir_path): os.makedirs(dir_path) path = os.path.join(dir_path, file_name) + if done.done: + last_file = os.path.join(dir_path, done.file_name) + if os.path.exists(last_file): + os.remove(last_file) done.done = True done.file_name = file_name - done.upload_time= datetime.now() + done.upload_time = datetime.now() done.save() destination = open(path, 'wb+') for chunk in file.chunks(): @@ -348,10 +352,11 @@ class SubmitView(APIView): context['error'] = "您没有次参加本作业" return Response(context) done = done.first() - context['data']=dict() - context['data']['done']=done.done - context['data']['file_name']=done.file_name - context['data']['work_name']=done.work.name + context['data'] = dict() + context['data']['done'] = done.done + context['data']['file_name'] = done.file_name + context['data']['work_name'] = done.work.name + context['data']['upload_time'] = done.upload_time return Response(context) @@ -359,6 +364,45 @@ class ExportView(APIView): def get(self, request): pass + class DownloadView(APIView): - def get(self,request): - pass + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + work_id = data.get('work_id') + try: + work_id = int(work_id) + except: + context['err_code'] = 1002 + context['error'] = "请求参数不正确" + return Response(context) + done = HomeWorkMembersModel.objects.filter(work__id=work_id, owner=user) + if not done.exists(): + context['err_code'] = 4004 + context['error'] = "您没有次参加本作业" + return Response(context) + done = done.first() + if not done.done: + context['err_code'] = 4004 + context['error'] = "您还没有提交本次作业" + return Response(context) + dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), + str(done.work.id)) + file_name = done.file_name + file = os.path.join(dir_path, file_name) + if not os.path.exists(file): + context['err_code'] = 4004 + context['error'] = "很抱歉,该文件已过期被清理" + return Response(context) + + file = open(file, 'rb') + response = FileResponse(file) + response['Content-Type'] = 'application/octet-stream' + response['Content-Disposition'] = "attachment; filename= {}".format(file_name) + return response -- Gitee From 49033daaa5180f868a954883d1f81e79fa114809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Fri, 13 Nov 2020 18:45:15 +0800 Subject: [PATCH 20/24] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=80=85=E5=8F=AF=E6=9F=A5=E7=9C=8B=E5=AE=8C=E6=88=90=E6=83=85?= =?UTF-8?q?=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeWork/urls.py | 6 ++- group/models.py | 1 - group/serializers.py | 6 +-- group/views.py | 4 -- work/serializers.py | 22 +++++++--- work/views.py | 101 ++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 118 insertions(+), 22 deletions(-) diff --git a/HomeWork/urls.py b/HomeWork/urls.py index 32c6e8c..b809d42 100644 --- a/HomeWork/urls.py +++ b/HomeWork/urls.py @@ -16,7 +16,7 @@ Including another URLconf from django.contrib import admin from django.urls import path from login.views import LoginView,LogOutView,MeView,RegisterView -from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView,DownloadView,ExportView +from work.views import HomeWorkView,MyHomeWorkNumView,MyHomeWorkView,SubmitView,DownloadView,ExportView,DoneListView from group.views import GroupView,MyGroupNumView,MyGroupView,GroupMembersView urlpatterns = [ path('admin/', admin.site.urls), @@ -33,5 +33,7 @@ urlpatterns = [ path('register/',RegisterView.as_view()), path('groupmembers/',GroupMembersView.as_view()), path('download/',DownloadView.as_view()), - path('export/',ExportView.as_view(),) + path('export/',ExportView.as_view()), + path('donelist/',DoneListView.as_view()), + ] diff --git a/group/models.py b/group/models.py index d24966b..1a15137 100644 --- a/group/models.py +++ b/group/models.py @@ -22,7 +22,6 @@ class GroupModel(models.Model): return str(self.name) def get_members(self): - yield self.owner join_groups = GroupMembersModel.objects.filter(group=self) for member in join_groups: yield member.user diff --git a/group/serializers.py b/group/serializers.py index c4a721a..57a1dfa 100644 --- a/group/serializers.py +++ b/group/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from .models import GroupModel +from .models import GroupModel,GroupMembersModel import re @@ -77,7 +77,7 @@ class GroupMembersSerializer(serializers.Serializer): def get_members(self, obj): members_list = list() - members = obj.get_members() + members = GroupMembersModel.objects.filter(group=obj).order_by('user__first_name') for member in members: - members_list.append({'id': member.id, 'name': member.first_name,'username':member.username}) + members_list.append({'id': member.user.id, 'name': member.user.first_name,'username':member.user.username}) return members_list diff --git a/group/views.py b/group/views.py index e379661..09f1eb2 100644 --- a/group/views.py +++ b/group/views.py @@ -292,10 +292,6 @@ class MyGroupView(APIView): context['err_code'] = 4003 context['error'] = "您已经加入该小组" return Response(context) - if group.owner == user: - context['err_code'] = 4003 - context['error'] = "不能加入自己创建的小组" - return Response(context) if group.password != password: context['err_code'] = 4002 context['error'] = "密码错误" diff --git a/work/serializers.py b/work/serializers.py index 9a9901a..aad0d90 100644 --- a/work/serializers.py +++ b/work/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from .models import HomeWorkInfModel +from .models import HomeWorkInfModel, HomeWorkMembersModel class HomeWorkUpSerializer(serializers.Serializer): # 用于登录的表单合法性验证,防止绕过前端验证 @@ -66,7 +66,6 @@ class HomeWorkInfSerializer(serializers.ModelSerializer): return groups_list - class HomeWorkCreateSerializer(serializers.ModelSerializer): class Meta: model = HomeWorkInfModel @@ -86,14 +85,25 @@ class HomeWorkSerializer(serializers.Serializer): end_time = serializers.DateTimeField() done = serializers.BooleanField() - def get_id(self,obj): + def get_id(self, obj): return obj.work.id - def get_name(self,obj): + def get_name(self, obj): return obj.work.name - def get_owner(self,obj): + def get_owner(self, obj): return obj.work.owner.first_name - def get_subject(self,obj): + def get_subject(self, obj): return obj.work.subject + + +class DoneListSerializer(serializers.ModelSerializer): + owner = serializers.SerializerMethodField() + + class Meta: + model = HomeWorkMembersModel + fields = ['id', 'done', 'file_name', 'upload_time', 'owner'] + + def get_owner(self, obj): + return {'name': obj.owner.first_name, 'id': obj.owner.id} diff --git a/work/views.py b/work/views.py index 7af0620..f10345d 100644 --- a/work/views.py +++ b/work/views.py @@ -1,6 +1,6 @@ from rest_framework.views import APIView from rest_framework.response import Response -from .serializers import HomeWorkUpSerializer, HomeWorkInfSerializer, HomeWorkSerializer, HomeWorkCreateSerializer +from .serializers import HomeWorkUpSerializer, HomeWorkInfSerializer, HomeWorkSerializer, HomeWorkCreateSerializer , DoneListSerializer from common.common import get_first_error from .models import HomeWorkInfModel, HomeWorkMembersModel from datetime import datetime @@ -360,11 +360,6 @@ class SubmitView(APIView): return Response(context) -class ExportView(APIView): - def get(self, request): - pass - - class DownloadView(APIView): def get(self, request): context = dict() @@ -406,3 +401,97 @@ class DownloadView(APIView): response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = "attachment; filename= {}".format(file_name) return response + +class ExportView(APIView): + def get(self, request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + work_id = data.get('work_id') + user_id=data.get('user_id') + try: + work_id = int(work_id) + except: + context['err_code'] = 1002 + context['error'] = "请求参数不正确" + return Response(context) + if user_id is not None: # 如果同时附带user_id,那就是点击了下载单个用户文件 + try: + user_id=int(user_id) + except: + context['err_code']= 1002 + context['error'] = "请求参数不正确" + return Response(context) + file_name_upload=data.get('file_name') + if file_name_upload is None: + context['err_code'] = 1002 + context['error'] = "请求参数不正确,没有文件名" + return Response(context) + done = HomeWorkMembersModel.objects.filter(work__id=work_id, owner__id=user_id) + if not done.exists(): + context['err_code'] = 4004 + context['error'] = "该用户没有参与本次作业" + return Response(context) + done = done.first() + if not done.done: + context['err_code'] = 4004 + context['error'] = "该用户还没有完成本次作业" + return Response(context) + dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), + str(done.work.id)) + file_name = done.file_name + if file_name != file_name_upload: + context['err_code'] = 3001 + context['error'] = "该文件已发生变化,请刷新页面重试" + return Response(context) + file = os.path.join(dir_path, file_name) + if not os.path.exists(file): + context['err_code'] = 4004 + context['error'] = "很抱歉,该文件已过期被清理" + return Response(context) + + file = open(file, 'rb') + response = FileResponse(file) + response['Content-Type'] = 'application/octet-stream' + response['Content-Disposition'] = "attachment; filename= {}".format(file_name) + return response + else: # 如果user_id为None,那么可以认为是导出操作 + pass + + +class DoneListView(APIView): + def get(self,request): + context = dict() + context['err_code'] = 0 + data = request.GET + user = request.user + if user.is_anonymous: + context['err_code'] = 1001 + context['error'] = "您还未登录" + return Response(context) + work_id = data.get('work_id') + try: + work_id = int(work_id) + except: + context['err_code'] = 1002 + context['error'] = "请求参数不正确" + return Response(context) + work=HomeWorkInfModel.objects.filter(id=work_id).order_by('done') + if not work.exists(): + context['err_code'] = 4004 + context['error'] = "没有找到请求的作业" + return Response(context) + work=work.first() + if user != work.owner: + context['err_code'] = 4003 + context['error'] = "您没有权限查看该内容" + return Response(context) + done = HomeWorkMembersModel.objects.filter(work__id=work_id).order_by('done','-upload_time') + data=DoneListSerializer(done,many=True).data + context['data']=data + return Response(context) \ No newline at end of file -- Gitee From 669a8c8d0fe833465908ca7c4e72f5456fae74b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Fri, 13 Nov 2020 20:48:35 +0800 Subject: [PATCH 21/24] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work/views.py | 97 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/work/views.py b/work/views.py index f10345d..2387fdd 100644 --- a/work/views.py +++ b/work/views.py @@ -1,6 +1,7 @@ from rest_framework.views import APIView from rest_framework.response import Response -from .serializers import HomeWorkUpSerializer, HomeWorkInfSerializer, HomeWorkSerializer, HomeWorkCreateSerializer , DoneListSerializer +from .serializers import HomeWorkUpSerializer, HomeWorkInfSerializer, HomeWorkSerializer, HomeWorkCreateSerializer, \ + DoneListSerializer from common.common import get_first_error from .models import HomeWorkInfModel, HomeWorkMembersModel from datetime import datetime @@ -291,13 +292,19 @@ class SubmitView(APIView): context['error'] = "您还未登录" return Response(context) work_id = data.get('work_id') - print(work_id) try: work_id = int(work_id) except: context['err_code'] = 1002 context['error'] = "请求参数不正确" return Response(context) + work = HomeWorkInfModel.objects.filter(id=work_id) + if not work.exists(): + context['err_code'] = 4004 + context['error'] = "请求的作业不存在" + return Response(context) + work = work.first() + done = HomeWorkMembersModel.objects.filter(work__id=work_id, owner=user) if not done.exists(): context['err_code'] = 4004 @@ -309,8 +316,9 @@ class SubmitView(APIView): context['err_code'] = 2001 context['error'] = "没有文件" return Response(context) - dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), - str(done.work.id)) + done.upload_time = datetime.now() + dir_path = os.path.join(os.getcwd(), "file", str(work.create_time.year), str(work.create_time.month), + str(work.id)) file_name = user.username + user.first_name + os.path.splitext(file.name)[1] if not os.path.exists(dir_path): os.makedirs(dir_path) @@ -321,7 +329,7 @@ class SubmitView(APIView): os.remove(last_file) done.done = True done.file_name = file_name - done.upload_time = datetime.now() + done.save() destination = open(path, 'wb+') for chunk in file.chunks(): @@ -377,6 +385,13 @@ class DownloadView(APIView): context['err_code'] = 1002 context['error'] = "请求参数不正确" return Response(context) + work = HomeWorkInfModel.objects.filter(id=work_id) + + if not work.exists(): + context['err_code'] = 4004 + context['error'] = "请求的作业不存在" + return Response(context) + work = work.first() done = HomeWorkMembersModel.objects.filter(work__id=work_id, owner=user) if not done.exists(): context['err_code'] = 4004 @@ -387,8 +402,8 @@ class DownloadView(APIView): context['err_code'] = 4004 context['error'] = "您还没有提交本次作业" return Response(context) - dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), - str(done.work.id)) + dir_path = os.path.join(os.getcwd(), "file", str(work.create_time.year), str(work.create_time.month), + str(work.id)) file_name = done.file_name file = os.path.join(dir_path, file_name) if not os.path.exists(file): @@ -402,6 +417,7 @@ class DownloadView(APIView): response['Content-Disposition'] = "attachment; filename= {}".format(file_name) return response + class ExportView(APIView): def get(self, request): context = dict() @@ -413,21 +429,34 @@ class ExportView(APIView): context['error'] = "您还未登录" return Response(context) work_id = data.get('work_id') - user_id=data.get('user_id') + user_id = data.get('user_id') try: work_id = int(work_id) except: context['err_code'] = 1002 context['error'] = "请求参数不正确" return Response(context) - if user_id is not None: # 如果同时附带user_id,那就是点击了下载单个用户文件 + + work = HomeWorkInfModel.objects.filter(id=work_id) + + if not work.exists(): + context['err_code'] = 4004 + context['error'] = "请求的作业不存在" + return Response(context) + work = work.first() + if user != work.owner: + context['err_code'] = 4003 + context['error'] = "您没有权限查看此内容" + return Response(context) + + if user_id is not None: # 如果同时附带user_id,那就是点击了下载单个用户文件 try: - user_id=int(user_id) + user_id = int(user_id) except: - context['err_code']= 1002 + context['err_code'] = 1002 context['error'] = "请求参数不正确" return Response(context) - file_name_upload=data.get('file_name') + file_name_upload = data.get('file_name') if file_name_upload is None: context['err_code'] = 1002 context['error'] = "请求参数不正确,没有文件名" @@ -442,8 +471,8 @@ class ExportView(APIView): context['err_code'] = 4004 context['error'] = "该用户还没有完成本次作业" return Response(context) - dir_path = os.path.join(os.getcwd(), "file", str(datetime.now().year), str(datetime.now().month), - str(done.work.id)) + dir_path = os.path.join(os.getcwd(), "file", str(work.create_time.year), str(work.create_time.month), + str(work.id)) file_name = done.file_name if file_name != file_name_upload: context['err_code'] = 3001 @@ -460,12 +489,34 @@ class ExportView(APIView): response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = "attachment; filename= {}".format(file_name) return response - else: # 如果user_id为None,那么可以认为是导出操作 - pass + else: # 如果user_id为None,那么可以认为是导出操作 + dir_path = os.path.join(os.getcwd(), "file", str(work.create_time.year), str(work.create_time.month), + str(work.id)) + if not os.path.exists(dir_path): + context['err_code'] = 4004 + context['error'] = "很抱歉,该文件已过期被清理" + return Response(context) + + from io import BytesIO + import zipfile + + temp_io = BytesIO() + + filelists = os.listdir(dir_path) + z = zipfile.ZipFile(temp_io, 'w', zipfile.ZIP_DEFLATED) + for fil in filelists: + filefullpath = os.path.join(dir_path, fil) + z.write(filefullpath, fil) + z.close() + temp_io.seek(0) + response = FileResponse(temp_io) + response['Content-Type'] = 'application/octet-stream' + response['Content-Disposition'] = "attachment;" + return response class DoneListView(APIView): - def get(self,request): + def get(self, request): context = dict() context['err_code'] = 0 data = request.GET @@ -481,17 +532,17 @@ class DoneListView(APIView): context['err_code'] = 1002 context['error'] = "请求参数不正确" return Response(context) - work=HomeWorkInfModel.objects.filter(id=work_id).order_by('done') + work = HomeWorkInfModel.objects.filter(id=work_id).order_by('done') if not work.exists(): context['err_code'] = 4004 context['error'] = "没有找到请求的作业" return Response(context) - work=work.first() + work = work.first() if user != work.owner: context['err_code'] = 4003 context['error'] = "您没有权限查看该内容" return Response(context) - done = HomeWorkMembersModel.objects.filter(work__id=work_id).order_by('done','-upload_time') - data=DoneListSerializer(done,many=True).data - context['data']=data - return Response(context) \ No newline at end of file + done = HomeWorkMembersModel.objects.filter(work__id=work_id).order_by('done', '-upload_time') + data = DoneListSerializer(done, many=True).data + context['data'] = data + return Response(context) -- Gitee From a8e5e9a46000d9f40527adf196b37939a2ddda55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Fri, 13 Nov 2020 21:57:11 +0800 Subject: [PATCH 22/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=BB=84=E5=91=98?= =?UTF-8?q?=E5=8F=AF=E7=94=A8=E5=B0=8F=E7=BB=84=E5=88=9B=E5=BB=BA=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group/models.py | 5 +++-- group/serializers.py | 8 +++++--- group/views.py | 19 +++++++++++++++++-- work/views.py | 26 +++++++++++++++++++++----- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/group/models.py b/group/models.py index 1a15137..6e27c77 100644 --- a/group/models.py +++ b/group/models.py @@ -17,7 +17,8 @@ class GroupModel(models.Model): db_index=True) password = models.CharField(max_length=20, verbose_name="小组密码", null=True) create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True) - + member_can_use = models.BooleanField(verbose_name='成员可使用该组创建作业',default=False) + members = models.ManyToManyField(to=User,verbose_name="成员",through='GroupMembersModel',related_name='Groups') def __str__(self): return str(self.name) @@ -35,7 +36,7 @@ class GroupMembersModel(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户", related_name="joined_groups", db_index=True) - group = models.ForeignKey(GroupModel, on_delete=models.CASCADE, verbose_name="小组", related_name="members") + group = models.ForeignKey(GroupModel, on_delete=models.CASCADE, verbose_name="小组") time = models.DateTimeField(auto_now_add=True, verbose_name="加入时间") def __str__(self): diff --git a/group/serializers.py b/group/serializers.py index 57a1dfa..0ae3581 100644 --- a/group/serializers.py +++ b/group/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from .models import GroupModel,GroupMembersModel +from .models import GroupModel, GroupMembersModel import re @@ -8,7 +8,7 @@ class GroupSerializer(serializers.ModelSerializer): class Meta: model = GroupModel - fields = ['id', 'name', 'desc', 'create_time', 'owner', 'members', 'password'] + fields = ['id', 'name', 'desc', 'create_time', 'owner', 'members', 'password', 'member_can_use'] def get_owner(self, obj): return obj.owner.first_name @@ -18,6 +18,7 @@ class GroupUnSerializer(serializers.Serializer): name = serializers.CharField() desc = serializers.CharField(required=False, default="") password = serializers.CharField() + member_can_use = serializers.BooleanField() def validate_name(self, name): if valid_group_information('name', name): @@ -79,5 +80,6 @@ class GroupMembersSerializer(serializers.Serializer): members_list = list() members = GroupMembersModel.objects.filter(group=obj).order_by('user__first_name') for member in members: - members_list.append({'id': member.user.id, 'name': member.user.first_name,'username':member.user.username}) + members_list.append( + {'id': member.user.id, 'name': member.user.first_name, 'username': member.user.username}) return members_list diff --git a/group/views.py b/group/views.py index 09f1eb2..e9f4c29 100644 --- a/group/views.py +++ b/group/views.py @@ -71,7 +71,7 @@ class GroupView(APIView): context['err_code'] = 2002 return Response(context) data = data.data - group = GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password']) + group = GroupModel.objects.create(owner=user, name=data['name'], desc=data['desc'], password=data['password'],member_can_use=data['member_can_use']) context['data'] = dict() context['data']['id'] = group.id return Response(context) @@ -115,7 +115,7 @@ class GroupView(APIView): context['err_code'] = 4003 context['error'] = "您无权执行此操作" return Response(context) - querys.update(name=data['name'], desc=data['desc'], password=data['password']) + querys.update(name=data['name'], desc=data['desc'], password=data['password'],member_can_use=data['member_can_use']) return Response(context) def delete(self, request): @@ -255,6 +255,14 @@ class MyGroupView(APIView): elif status == "owner": groups = GroupModel.objects.order_by('-create_time').filter(owner=user)[start:end] context['data'] = CreateGroupsSerializer(groups, many=True).data + elif status == "can_use": + groups1 = GroupModel.objects.order_by('-create_time').filter(owner=user) + groups2 = user.Groups.filter(member_can_use=True) + groups = groups1 | groups2 + groups= groups.distinct() + groups.order_by('-create_time') + groups = groups[start:end] + context['data'] = CreateGroupsSerializer(groups, many=True).data else: context['err_code'] = 2001 context['error'] = "请求参数不正确" @@ -319,6 +327,13 @@ class MyGroupNumView(APIView): context['data'] = GroupMembersModel.objects.filter(user=user).count() elif status == "owner": context['data'] = GroupModel.objects.filter(owner=user).count() + elif status == "can_use": + groups1 = GroupModel.objects.order_by('-create_time').filter(owner=user) + groups2 = user.Groups.filter(member_can_use=True) + groups = groups1 | groups2 + groups = groups.distinct() + groups.order_by('-create_time') + context['data'] = groups.count() else: context['err_code'] = 2001 context['error'] = "请求参数不正确" diff --git a/work/views.py b/work/views.py index 2387fdd..e7cff97 100644 --- a/work/views.py +++ b/work/views.py @@ -8,7 +8,7 @@ from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication from django.http import QueryDict, FileResponse import os - +from group.models import GroupModel,GroupMembersModel class CsrfExemptSessionAuthentication(SessionAuthentication): @@ -44,16 +44,32 @@ class HomeWorkView(APIView): return Response(context) groups = str(groups) groups = groups.split(',') - groups_in = list() + groups_int = list() try: for group in groups: group = int(group) - groups_in.append(group) + groups_int.append(group) except: context['error'] = "小组id只能为int" context['err_code'] = 2002 return Response(context) - + for group_id in groups_int: + group = GroupModel.objects.filter(id=group_id) + if not group.exists(): + context['error'] = "添加了无效的小组" + context['err_code'] = 4004 + return Response(context) + group=group.first() + if user == group.owner: + continue + if not GroupMembersModel.objects.filter(user=user,group__id=group_id).exists(): + context['error'] = "添加了无效的小组" + context['err_code'] = 4004 + return Response(context) + if not group.member_can_use: + context['error'] = "添加了无效的小组" + context['err_code'] = 4004 + return Response(context) homework = HomeWorkInfModel.objects.create(name=data['name'], type=data['type'], subject=data['subject'], @@ -71,7 +87,7 @@ class HomeWorkView(APIView): ), ) - for group_id in groups: + for group_id in groups_int: homework.groups.add(group_id) context['data'] = dict() context['data']['id'] = homework.id -- Gitee From 17f5aede6e7eb8dd5e81dcf09671a0867055663c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 16 Nov 2020 17:11:35 +0800 Subject: [PATCH 23/24] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=96=87=E4=BB=B6=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E8=AF=B7=E6=B1=82=E5=8F=82=E6=95=B0=E5=AD=98?= =?UTF-8?q?=E5=9C=A8status=E5=88=99=E4=B8=8D=E8=BF=94=E5=9B=9E=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work/views.py | 158 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 24 deletions(-) diff --git a/work/views.py b/work/views.py index e7cff97..00a62fd 100644 --- a/work/views.py +++ b/work/views.py @@ -8,7 +8,8 @@ from datetime import datetime from rest_framework.authentication import SessionAuthentication, BasicAuthentication from django.http import QueryDict, FileResponse import os -from group.models import GroupModel,GroupMembersModel +from group.models import GroupModel, GroupMembersModel + class CsrfExemptSessionAuthentication(SessionAuthentication): @@ -59,10 +60,10 @@ class HomeWorkView(APIView): context['error'] = "添加了无效的小组" context['err_code'] = 4004 return Response(context) - group=group.first() + group = group.first() if user == group.owner: continue - if not GroupMembersModel.objects.filter(user=user,group__id=group_id).exists(): + if not GroupMembersModel.objects.filter(user=user, group__id=group_id).exists(): context['error'] = "添加了无效的小组" context['err_code'] = 4004 return Response(context) @@ -426,7 +427,9 @@ class DownloadView(APIView): context['err_code'] = 4004 context['error'] = "很抱歉,该文件已过期被清理" return Response(context) - + if data.get('status'): + context['er_code'] = 0 + return Response(context) file = open(file, 'rb') response = FileResponse(file) response['Content-Type'] = 'application/octet-stream' @@ -436,6 +439,7 @@ class DownloadView(APIView): class ExportView(APIView): def get(self, request): + context = dict() context['err_code'] = 0 data = request.GET @@ -494,17 +498,20 @@ class ExportView(APIView): context['err_code'] = 3001 context['error'] = "该文件已发生变化,请刷新页面重试" return Response(context) - file = os.path.join(dir_path, file_name) - if not os.path.exists(file): + file_name = os.path.join(dir_path, file_name) + if not os.path.exists(file_name): context['err_code'] = 4004 context['error'] = "很抱歉,该文件已过期被清理" return Response(context) - - file = open(file, 'rb') + if data.get('status'): + context['er_code'] = 0 + return Response(context) + file = open(file_name, 'rb') response = FileResponse(file) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = "attachment; filename= {}".format(file_name) return response + else: # 如果user_id为None,那么可以认为是导出操作 dir_path = os.path.join(os.getcwd(), "file", str(work.create_time.year), str(work.create_time.month), str(work.id)) @@ -512,23 +519,40 @@ class ExportView(APIView): context['err_code'] = 4004 context['error'] = "很抱歉,该文件已过期被清理" return Response(context) + export = export_list.get(str(work_id)) + if export is None: + export_fun(dir_path, work_id) + context['err_code'] = 0 + context['data'] = dict() + context['data']['msg'] = "后台已经开始导出,请您耐心等待" + context['data']['done'] = False + return Response(context) + else: + if export.get_error_status(): + context['er_code'] = 5001 + context['error'] = export.get_error() + return Response(context) - from io import BytesIO - import zipfile - - temp_io = BytesIO() - - filelists = os.listdir(dir_path) - z = zipfile.ZipFile(temp_io, 'w', zipfile.ZIP_DEFLATED) - for fil in filelists: - filefullpath = os.path.join(dir_path, fil) - z.write(filefullpath, fil) - z.close() - temp_io.seek(0) - response = FileResponse(temp_io) - response['Content-Type'] = 'application/octet-stream' - response['Content-Disposition'] = "attachment;" - return response + if export.get_done_status(): + status = data.get('status') + if status is not None: + context['er_code'] = 0 + context['data'] = dict() + context['done'] = True + return Response(context) + else: + file = export.file_name + file = open(file, 'rb') + response = FileResponse(file) + response['Content-Type'] = 'application/octet-stream' + response['Content-Disposition'] = "attachment;" + return response + else: + context['err_code'] = 0 + context['data'] = dict() + context['data']['msg'] = "导出正在进行中,请您稍后" + context['data']['done'] = False + return Response(context) class DoneListView(APIView): @@ -562,3 +586,89 @@ class DoneListView(APIView): data = DoneListSerializer(done, many=True).data context['data'] = data return Response(context) + + +export_list = dict() + + +def export_fun(dir_path, work_id): + import threading + t = threading.Thread(target=export_thread, args=(dir_path, work_id)) + t.start() + + +def export_thread(dir_path, work_id): + export = ExportThread(dir_path, work_id) + export_list[str(work_id)] = export + export.export() + + + + +class ExportThread: + def __init__(self, dir_path, work_id): + self.dir_path = dir_path + self.file_name = os.path.join(self.dir_path, 'export.zip') + self.is_done = False + self.error = False + self.err_msg = '' + self.work_id = work_id + + def export(self): + try: + import zipfile + filelists = os.listdir(self.dir_path) + z = zipfile.ZipFile(self.file_name, 'w', zipfile.ZIP_DEFLATED) + for fil in filelists: + filefullpath = os.path.join(self.dir_path, fil) + z.write(filefullpath,arcname = os.path.join('作业',fil)) + z.close() + except Exception as e: + self.error = True + self.err_msg = str(e) + self.waiting() + + def waiting(self): + self.is_done = True + import time + time.sleep(120) + self.end() + + def get_done_status(self): + if os.path.exists(self.file_name): + return self.is_done + else: + self.export() + return False + + def get_error_status(self): + return self.error + + def get_error(self): + return self.err_msg + + def end(self): + if str(self.work_id) in export_list: + del export_list[str(self.work_id)] + del_fun(self.file_name) + return + + +def del_fun(file_name): + import threading + t = threading.Thread(target=del_thread, args=(file_name,)) + t.start() + + +def del_thread(file_name): + import time + i = 0 + while i < 10: + if os.path.exists(file_name): + try: + os.remove(file_name) + except: + time.sleep(60) + i += 1 + else: + return -- Gitee From c331001754150b883aa1f4321c21799c8ef3d2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E4=BA=9A=E5=AE=81?= <1553770945@qq.com> Date: Mon, 16 Nov 2020 19:52:38 +0800 Subject: [PATCH 24/24] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work/views.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/work/views.py b/work/views.py index 00a62fd..c594866 100644 --- a/work/views.py +++ b/work/views.py @@ -619,9 +619,10 @@ class ExportThread: import zipfile filelists = os.listdir(self.dir_path) z = zipfile.ZipFile(self.file_name, 'w', zipfile.ZIP_DEFLATED) + name = HomeWorkInfModel.objects.get(id=int(self.work_id)).name for fil in filelists: filefullpath = os.path.join(self.dir_path, fil) - z.write(filefullpath,arcname = os.path.join('作业',fil)) + z.write(filefullpath,arcname = os.path.join(name,fil)) z.close() except Exception as e: self.error = True @@ -635,11 +636,7 @@ class ExportThread: self.end() def get_done_status(self): - if os.path.exists(self.file_name): - return self.is_done - else: - self.export() - return False + return self.is_done def get_error_status(self): return self.error -- Gitee