diff --git a/access/admin.py b/access/admin.py index 8449d50..091e649 100755 --- a/access/admin.py +++ b/access/admin.py @@ -1,11 +1,9 @@ from django.contrib import admin from access.models.other import Invite, Account, ResetPassword, UserActivity -from access.models.progress import ProgressLesson from access.models.user import User admin.site.register(User) admin.site.register(Account) admin.site.register(Invite) admin.site.register(ResetPassword) -admin.site.register(ProgressLesson) admin.site.register(UserActivity) diff --git a/access/migrations/0009_auto_20180125_1643.py b/access/migrations/0004_auto_20180129_0933.py similarity index 70% rename from access/migrations/0009_auto_20180125_1643.py rename to access/migrations/0004_auto_20180129_0933.py index 338f94d..7440266 100644 --- a/access/migrations/0009_auto_20180125_1643.py +++ b/access/migrations/0004_auto_20180129_0933.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-25 16:43 +# Generated by Django 1.11.6 on 2018-01-29 09:33 from __future__ import unicode_literals from django.db import migrations @@ -8,18 +8,10 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('access', '0008_auto_20171220_1325'), + ('access', '0003_useractivity'), ] operations = [ - migrations.RemoveField( - model_name='pivotprogressvertex', - name='progress', - ), - migrations.RemoveField( - model_name='pivotprogressvertex', - name='teacher', - ), migrations.AlterUniqueTogether( name='progress', unique_together=set([]), @@ -32,10 +24,22 @@ class Migration(migrations.Migration): model_name='progress', name='user', ), - migrations.DeleteModel( - name='PivotProgressVertex', + migrations.AlterUniqueTogether( + name='progresslesson', + unique_together=set([]), + ), + migrations.RemoveField( + model_name='progresslesson', + name='progress', + ), + migrations.RemoveField( + model_name='progresslesson', + name='teacher', ), migrations.DeleteModel( name='Progress', ), + migrations.DeleteModel( + name='ProgressLesson', + ), ] diff --git a/access/models/progress.py b/access/models/progress.py deleted file mode 100644 index 7ef76be..0000000 --- a/access/models/progress.py +++ /dev/null @@ -1,88 +0,0 @@ -from django.conf import settings -from django.contrib.postgres.fields import ArrayField -from django.db import models -from model_utils import Choices -from courses.api import CourseProgressApi - - -class Progress(models.Model): - hidden_lessons = ArrayField( - models.UUIDField(verbose_name="Токен урока", unique=True, editable=False), - default=[], - verbose_name='Список скрытых уроков', - ) - teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь по умолчанию", - related_name='teacher_progress') - user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент') - course_token = models.UUIDField(verbose_name="Токен курса", editable=False) - - def progress_status(self, sorted_token_list): - """ - Возвращает порядок активной темы и урока или ничего - - :return: (topic_sort, lesson_sort) or None - """ - - token_list = [i.lesson_token for i in self.progresslesson_set.filter(status='done')] - - x = (1, 1) - - for idx_topic, lesson_list in enumerate(sorted_token_list): - for idx_lesson, lesson_token in enumerate(lesson_list): - if lesson_token in token_list: - x = None - - elif x is None: - x = (idx_topic+1, idx_lesson+1) - - return x - - def __str__(self): - return '%s' % (self.user.email,) - - class Meta: - verbose_name = 'Прогресс пользователя' - verbose_name_plural = 'Прогресс пользователя' - unique_together = (("user", "course_token"),) - - -class ProgressLesson(models.Model): - progress = models.ForeignKey(to=Progress) - lesson_token = models.UUIDField(verbose_name="Токен урока", editable=False) - teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь",) - date = models.DateTimeField(verbose_name='Дата зачтения задания', blank=True, null=True) - STATUSES = Choices('done', 'wait', 'fail') - status = models.CharField(choices=STATUSES, default=STATUSES.wait, max_length=20) - comment_tokens = ArrayField(models.UUIDField(verbose_name="Токен комента", editable=False), default=[]) - - def __str__(self): - return self.progress.user.email - - class Meta: - verbose_name = 'Прохождение уроков' - verbose_name_plural = 'Прохождение урока' - unique_together = ('progress', 'lesson_token') - - -# class UserLessonAnswer(models.Model): -# progress_lesson = models.ForeignKey(to=ProgressLesson) -# date = models.DateTimeField(verbose_name='Дата сдачи', auto_now_add=True) -# reviewer = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Проверяющий",) -# -# class Meta: -# verbose_name = 'Блок ответов пользователя' -# verbose_name_plural = 'Блоки ответов пользователя' -# -# -# class AnswerItem(models.Model): -# STATUSES = Choices('done', 'wait', 'fail') -# -# lesson_answer = models.ForeignKey(to=UserLessonAnswer) -# question = models.TextField(verbose_name='Вопрос') # TODO подумать над хранением токена вопроса -# value = models.TextField(verbose_name='Ответ') -# comment = models.TextField(verbose_name='Комент', blank=True, null=True) -# status = models.CharField(choices=STATUSES, default=STATUSES.wait, max_length=20) -# -# class Meta: -# verbose_name = 'Ответ пользователя' -# verbose_name_plural = 'Ответы пользователя' diff --git a/access/serializers.py b/access/serializers.py index bc88c84..425ffd5 100644 --- a/access/serializers.py +++ b/access/serializers.py @@ -2,52 +2,8 @@ from django.contrib.auth import get_user_model from rest_framework import serializers from access.models.other import Account -from access.models.progress import ProgressLesson -from progress.models import Progress from achievements.serialers import DiplomaSerializer, AchievementsSerializer -from courses.api import CourseProgressApi - - -class ProgressLessonSerializer(serializers.ModelSerializer): - teacher = serializers.SerializerMethodField() - - class Meta: - model = ProgressLesson - exclude = ('id', 'progress') - - @staticmethod - def get_teacher(self): - return self.teacher.get_full_name() - - -class ProgressAnalyticSerializer(serializers.ModelSerializer): - name = serializers.SerializerMethodField() - email = serializers.SerializerMethodField() - - class Meta: - model = Progress - fields = ('name', 'email',) - - @staticmethod - def get_name(self): - return self.user.get_full_name() - - @staticmethod - def get_email(self): - return self.user.email - - - -class ProgressSerializer(serializers.ModelSerializer): - lessons = serializers.SerializerMethodField() - - class Meta: - model = Progress - fields = ('lessons', 'course_token') - - @staticmethod - def get_lessons(self): - return [ProgressLessonSerializer(i).data for i in self.progresslesson_set.all()] +from progress.serializers import ProgressSerializer class AccountSerializer(serializers.ModelSerializer): diff --git a/access/urls.py b/access/urls.py index 59946d8..3851074 100644 --- a/access/urls.py +++ b/access/urls.py @@ -13,8 +13,4 @@ urlpatterns = [ url(r'login/$', views.LoginView.as_view()), url(r'logout/$', views.LogoutView.as_view()), url(r'reset/$', views.ResetPasswordView.as_view()), - url(r'progress/$', views.UpdateProgress.as_view()), - url(r'progress_detail/upload/(?P[0-9A-Fa-f-]+)/$', views.UploadCourseProgressUserView.as_view()), - url(r'progress_detail/(?P[0-9A-Fa-f-]+)/$', views.CourseProgressUserView.as_view()), - url(r'progress_dynamic/(?P[0-9A-Fa-f-]+)/$', views.CourseProgressDynamicView.as_view()), ] \ No newline at end of file diff --git a/access/views.py b/access/views.py index 0998d9e..f64b15c 100644 --- a/access/views.py +++ b/access/views.py @@ -16,10 +16,7 @@ from rest_framework.response import Response from rest_framework.views import APIView from access.models.other import Invite, ResetPassword -from access.models.progress import ProgressLesson -from progress.models import Progress -from access.serializers import UserSelfSerializer, UserSearchSerializer, ProgressLessonSerializer, \ - ProgressAnalyticSerializer +from access.serializers import UserSelfSerializer, UserSearchSerializer from courses.api import CourseProgressApi @@ -236,41 +233,6 @@ class LogoutView(APIView): return Response(status=204) -class UpdateProgress(APIView): - renderer_classes = (JSONRenderer,) - - @staticmethod - def post(request): - """ - На вход обязательно передаётся параметр id (id узла). - """ - lesson_token = request.JSON.get('lesson_token', None) - course_token = request.JSON.get('course_token', None) - if lesson_token is None or course_token is None: - return Response('Не передан слаг курса или токен урока', status=400) - try: - p = Progress.objects.get(user=request.user, course_token=course_token) - try: - pv = ProgressLesson.objects.get( - progress=p, - lesson_token=lesson_token, - ) - - except ProgressLesson.DoesNotExist: - pv = ProgressLesson.objects.create( - date=datetime.datetime.now(), - teacher=p.teacher, - progress=p, - lesson_token=lesson_token, - ) - pv.status = ProgressLesson.STATUSES.done - pv.save() - return Response(ProgressLessonSerializer(pv).data, status=200) - - except Progress.DoesNotExist: - return Response('Не найден прогресс по заданным параметрам', status=404) - - class UserGuardView(APIView): renderer_classes = (JSONRenderer,) permission_classes = (IsAuthenticated,) @@ -303,73 +265,6 @@ class UserGuardView(APIView): return res_403 -class CourseProgressDynamicView(APIView): - renderer_classes = (JSONRenderer,) - - @staticmethod - def get(request, token): - if request.user.is_authenticated() and request.user.is_staff: - try: - progresses = Progress.objects.filter(course_token=token) - res = {} - for i in progresses: - key = i.progresslesson_set.filter(status="done").count() - res[key] = 1 if not key in res.keys() else res[key] + 1 - return Response(res, status=200) - except ValidationError: - return Response("Bad request", status=400) - - return Response(status=403) - - -class CourseProgressUserView(APIView): - renderer_classes = (JSONRenderer,) - - @staticmethod - def get(request, token): - if request.user.is_authenticated() and request.user.is_staff: - try: - res = [] - sorted_token_list = CourseProgressApi.get_topic_lesson(token) - for p in Progress.objects.filter(course_token=token): - progress = ProgressAnalyticSerializer(p).data - progress['progress_course'] = p.progress_status(sorted_token_list) - res.append(progress) - return Response(res, status=200) - except ValidationError: - return Response("Bad request", status=400) - - return Response(status=403) - - -class UploadCourseProgressUserView(APIView): - renderer_classes = (JSONRenderer,) - - @staticmethod - def get(request, token): - if request.user.is_authenticated() and request.user.is_staff: - try: - response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename="%s.csv"' % token - sorted_token_list = CourseProgressApi.get_topic_lesson(token) - writer = csv.writer(response) - writer.writerow(['Имя', 'Почта', 'Последняя тема', 'Последний урок']) - - for p in Progress.objects.filter(course_token=token): - progress = ProgressAnalyticSerializer(p).data - progress['progress_course'] = p.progress_status(sorted_token_list) - writer.writerow([ - progress['name'], - progress['email'], - progress['progress_course'] and progress['progress_course'][0], - progress['progress_course'] and progress['progress_course'][1], - ]) - return response - except ValidationError: - return Response("Bad request", status=400) - return Response(status=403) - - class MinUserView(APIView): renderer_classes = (JSONRenderer,) diff --git a/api_v1/urls.py b/api_v1/urls.py index 176a568..bcfb4d0 100644 --- a/api_v1/urls.py +++ b/api_v1/urls.py @@ -4,7 +4,7 @@ urlpatterns = [ url(r'courses/', include('courses.urls')), url(r'users/', include('access.urls')), url(r'library/', include('library.urls')), - # url(r'finance/', include('finance.urls')), + url(r'finance/', include('finance.urls')), url(r'storage/', include('storage.urls')), url(r'progress/', include('progress.urls')), ] diff --git a/csv/load_comments.py b/csv/load_comments.py index 150e2a6..6922d78 100644 --- a/csv/load_comments.py +++ b/csv/load_comments.py @@ -1,6 +1,4 @@ import csv -import random -import string import django import os @@ -15,7 +13,7 @@ django.setup() from storage.models import Comment, File from courses.models import Lesson -from access.models.progress import ProgressLesson, Progress +from progress.models import ProgressLesson, Progress if __name__ == '__main__': csv.field_size_limit(500 * 1024 * 1024) diff --git a/csv/load_perm.py b/csv/load_perm.py index 900005c..f5bba11 100644 --- a/csv/load_perm.py +++ b/csv/load_perm.py @@ -14,10 +14,10 @@ django.setup() from django.contrib.auth.models import Group from django.contrib.auth import get_user_model -from access.models.progress import ProgressLesson -from progress.models import Progress +from progress.models import ProgressLesson, Progress from courses.models import Lesson, Course + if __name__ == '__main__': Progress.objects.all().delete() ProgressLesson.objects.all().delete() diff --git a/progress/admin.py b/progress/admin.py index 0e07352..fc4f9eb 100644 --- a/progress/admin.py +++ b/progress/admin.py @@ -1,6 +1,8 @@ from django.contrib import admin # Register your models here. -from progress.models import Progress +from progress.models import ProgressLesson, Progress + admin.site.register(Progress) +admin.site.register(ProgressLesson) diff --git a/progress/apps.py b/progress/apps.py index 07fee92..1e24c0b 100644 --- a/progress/apps.py +++ b/progress/apps.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.apps import AppConfig diff --git a/progress/migrations/0001_initial.py b/progress/migrations/0001_initial.py index f023e24..9abd9d4 100644 --- a/progress/migrations/0001_initial.py +++ b/progress/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-25 16:41 +# Generated by Django 1.11.6 on 2018-01-29 09:31 from __future__ import unicode_literals from django.conf import settings @@ -17,42 +17,42 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='PivotProgressVertex', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('vertex', models.CharField(blank=True, max_length=15, verbose_name='Ссылки на узлы')), - ('status', models.SmallIntegerField(choices=[(2, 'Выполненно'), (1, 'Ожидание'), (0, 'Не выполненно')], default=0)), - ('comment', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=15, unique=True, verbose_name='Ссылки на комменты'), default=[], size=None)), - ('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата зачтения задания')), - ], - ), migrations.CreateModel( name='Progress', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('route', models.CharField(blank=True, max_length=15, null=True, verbose_name='Токен прохождения')), - ('course', models.CharField(max_length=127, verbose_name='Слаг курса')), + ('hidden_lessons', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, unique=True, verbose_name='Токен урока'), default=[], size=None, verbose_name='Список скрытых уроков')), + ('course_token', models.UUIDField(editable=False, verbose_name='Токен курса')), ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teacher_progress', to=settings.AUTH_USER_MODEL, verbose_name='Преподователь по умолчанию')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент')), ], options={ - 'verbose_name_plural': 'Прогресс пользователя', 'verbose_name': 'Прогресс пользователя', + 'verbose_name_plural': 'Прогресс пользователя', }, ), - migrations.AddField( - model_name='pivotprogressvertex', - name='progress', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='progress.Progress'), + migrations.CreateModel( + name='ProgressLesson', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('lesson_token', models.UUIDField(editable=False, verbose_name='Токен урока')), + ('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата зачтения задания')), + ('status', models.CharField(choices=[('done', 'done'), ('wait', 'wait'), ('fail', 'fail')], default='wait', max_length=20)), + ('comment_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, verbose_name='Токен комента'), default=[], size=None)), + ('progress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='progress.Progress')), + ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Преподователь')), + ], + options={ + 'verbose_name': 'Прохождение уроков', + 'verbose_name_plural': 'Прохождение урока', + }, ), - migrations.AddField( - model_name='pivotprogressvertex', - name='teacher', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Преподователь'), + migrations.AlterUniqueTogether( + name='progresslesson', + unique_together=set([('progress', 'lesson_token')]), ), migrations.AlterUniqueTogether( name='progress', - unique_together=set([('user', 'route')]), + unique_together=set([('user', 'course_token')]), ), ] diff --git a/progress/models.py b/progress/models.py index adb61a1..7ef76be 100644 --- a/progress/models.py +++ b/progress/models.py @@ -1,16 +1,41 @@ from django.conf import settings from django.contrib.postgres.fields import ArrayField from django.db import models - -# Create your models here. +from model_utils import Choices +from courses.api import CourseProgressApi class Progress(models.Model): + hidden_lessons = ArrayField( + models.UUIDField(verbose_name="Токен урока", unique=True, editable=False), + default=[], + verbose_name='Список скрытых уроков', + ) teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь по умолчанию", related_name='teacher_progress') user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент') - route = models.CharField(max_length=15, verbose_name='Токен прохождения', blank=True, null=True) - course = models.CharField(max_length=127, verbose_name='Слаг курса') + course_token = models.UUIDField(verbose_name="Токен курса", editable=False) + + def progress_status(self, sorted_token_list): + """ + Возвращает порядок активной темы и урока или ничего + + :return: (topic_sort, lesson_sort) or None + """ + + token_list = [i.lesson_token for i in self.progresslesson_set.filter(status='done')] + + x = (1, 1) + + for idx_topic, lesson_list in enumerate(sorted_token_list): + for idx_lesson, lesson_token in enumerate(lesson_list): + if lesson_token in token_list: + x = None + + elif x is None: + x = (idx_topic+1, idx_lesson+1) + + return x def __str__(self): return '%s' % (self.user.email,) @@ -18,18 +43,46 @@ class Progress(models.Model): class Meta: verbose_name = 'Прогресс пользователя' verbose_name_plural = 'Прогресс пользователя' - unique_together = (("user", "route"),) + unique_together = (("user", "course_token"),) -class PivotProgressVertex(models.Model): - VERTEX_STATUS = ( - (2, 'Выполненно'), - (1, 'Ожидание'), - (0, 'Не выполненно'), - ) - teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь",) +class ProgressLesson(models.Model): progress = models.ForeignKey(to=Progress) - vertex = models.CharField(max_length=15, blank=True, verbose_name='Ссылки на узлы') - status = models.SmallIntegerField(choices=VERTEX_STATUS, default=0) - comment = ArrayField(models.CharField(max_length=15, verbose_name='Ссылки на комменты', unique=True), default=[]) - date = models.DateTimeField(verbose_name='Дата зачтения задания', blank=True, null=True) \ No newline at end of file + lesson_token = models.UUIDField(verbose_name="Токен урока", editable=False) + teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь",) + date = models.DateTimeField(verbose_name='Дата зачтения задания', blank=True, null=True) + STATUSES = Choices('done', 'wait', 'fail') + status = models.CharField(choices=STATUSES, default=STATUSES.wait, max_length=20) + comment_tokens = ArrayField(models.UUIDField(verbose_name="Токен комента", editable=False), default=[]) + + def __str__(self): + return self.progress.user.email + + class Meta: + verbose_name = 'Прохождение уроков' + verbose_name_plural = 'Прохождение урока' + unique_together = ('progress', 'lesson_token') + + +# class UserLessonAnswer(models.Model): +# progress_lesson = models.ForeignKey(to=ProgressLesson) +# date = models.DateTimeField(verbose_name='Дата сдачи', auto_now_add=True) +# reviewer = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Проверяющий",) +# +# class Meta: +# verbose_name = 'Блок ответов пользователя' +# verbose_name_plural = 'Блоки ответов пользователя' +# +# +# class AnswerItem(models.Model): +# STATUSES = Choices('done', 'wait', 'fail') +# +# lesson_answer = models.ForeignKey(to=UserLessonAnswer) +# question = models.TextField(verbose_name='Вопрос') # TODO подумать над хранением токена вопроса +# value = models.TextField(verbose_name='Ответ') +# comment = models.TextField(verbose_name='Комент', blank=True, null=True) +# status = models.CharField(choices=STATUSES, default=STATUSES.wait, max_length=20) +# +# class Meta: +# verbose_name = 'Ответ пользователя' +# verbose_name_plural = 'Ответы пользователя' diff --git a/progress/serializers.py b/progress/serializers.py index 17e7a8d..d4bb4c4 100644 --- a/progress/serializers.py +++ b/progress/serializers.py @@ -1,32 +1,44 @@ from rest_framework import serializers -from .models import PivotProgressVertex, Progress +from progress.models import ProgressLesson, Progress -class PivotProgressSerializer(serializers.ModelSerializer): - status = serializers.SerializerMethodField() +class ProgressLessonSerializer(serializers.ModelSerializer): teacher = serializers.SerializerMethodField() class Meta: - model = PivotProgressVertex + model = ProgressLesson exclude = ('id', 'progress') - @staticmethod - def get_status(self): - return self.get_status_display() - @staticmethod def get_teacher(self): return self.teacher.get_full_name() +class ProgressAnalyticSerializer(serializers.ModelSerializer): + name = serializers.SerializerMethodField() + email = serializers.SerializerMethodField() + + class Meta: + model = Progress + fields = ('name', 'email',) + + @staticmethod + def get_name(self): + return self.user.get_full_name() + + @staticmethod + def get_email(self): + return self.user.email + + class ProgressSerializer(serializers.ModelSerializer): - vertexes = serializers.SerializerMethodField() + lessons = serializers.SerializerMethodField() class Meta: model = Progress - fields = ('route', 'vertexes', 'course') + fields = ('lessons', 'course_token') @staticmethod - def get_vertexes(self): - return [PivotProgressSerializer(i).data for i in self.pivotprogressvertex_set.all()] \ No newline at end of file + def get_lessons(self): + return [ProgressLessonSerializer(i).data for i in self.progresslesson_set.all()] diff --git a/progress/urls.py b/progress/urls.py index 949cf8f..3f43770 100644 --- a/progress/urls.py +++ b/progress/urls.py @@ -2,6 +2,10 @@ from django.conf.urls import url from progress import views + urlpatterns = [ url(r'$', views.UpdateProgress.as_view()), -] + url(r'progress_detail/upload/(?P[0-9A-Fa-f-]+)/$', views.UploadCourseProgressUserView.as_view()), + url(r'progress_detail/(?P[0-9A-Fa-f-]+)/$', views.CourseProgressUserView.as_view()), + url(r'progress_dynamic/(?P[0-9A-Fa-f-]+)/$', views.CourseProgressDynamicView.as_view()), +] \ No newline at end of file diff --git a/progress/views.py b/progress/views.py index bf3a196..0bc2a92 100644 --- a/progress/views.py +++ b/progress/views.py @@ -1,14 +1,18 @@ import datetime +import csv +from django.http import HttpResponse from django.shortcuts import render # Create your views here. +from rest_framework.exceptions import ValidationError from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView -from .models import Progress, PivotProgressVertex -from .serializers import PivotProgressSerializer +from courses.api import CourseProgressApi +from progress.models import Progress, ProgressLesson +from progress.serializers import ProgressLessonSerializer, ProgressAnalyticSerializer class UpdateProgress(APIView): @@ -19,28 +23,95 @@ class UpdateProgress(APIView): """ На вход обязательно передаётся параметр id (id узла). """ - token = request.JSON.get('token', None) - course = request.JSON.get('slug', None) - if token is None or course is None: + lesson_token = request.JSON.get('lesson_token', None) + course_token = request.JSON.get('course_token', None) + if lesson_token is None or course_token is None: return Response('Не передан слаг курса или токен урока', status=400) try: - p = Progress.objects.get(user=request.user, course=course) + p = Progress.objects.get(user=request.user, course_token=course_token) try: - pv = PivotProgressVertex.objects.get( + pv = ProgressLesson.objects.get( progress=p, - vertex=token, + lesson_token=lesson_token, ) - except PivotProgressVertex.DoesNotExist: - pv = PivotProgressVertex.objects.create( + except ProgressLesson.DoesNotExist: + pv = ProgressLesson.objects.create( date=datetime.datetime.now(), teacher=p.teacher, progress=p, - vertex=token, + lesson_token=lesson_token, ) - pv.status = 2 + pv.status = ProgressLesson.STATUSES.done pv.save() - return Response(PivotProgressSerializer(pv).data, status=200) + return Response(ProgressLessonSerializer(pv).data, status=200) except Progress.DoesNotExist: - return Response('Не найден прогресс по заданным параметрам', status=404) \ No newline at end of file + return Response('Не найден прогресс по заданным параметрам', status=404) + + +class CourseProgressDynamicView(APIView): + renderer_classes = (JSONRenderer,) + + @staticmethod + def get(request, token): + if request.user.is_authenticated() and request.user.is_staff: + try: + progresses = Progress.objects.filter(course_token=token) + res = {} + for i in progresses: + key = i.progresslesson_set.filter(status="done").count() + res[key] = 1 if not key in res.keys() else res[key] + 1 + return Response(res, status=200) + except ValidationError: + return Response("Bad request", status=400) + + return Response(status=403) + + +class CourseProgressUserView(APIView): + renderer_classes = (JSONRenderer,) + + @staticmethod + def get(request, token): + if request.user.is_authenticated() and request.user.is_staff: + try: + res = [] + sorted_token_list = CourseProgressApi.get_topic_lesson(token) + for p in Progress.objects.filter(course_token=token): + progress = ProgressAnalyticSerializer(p).data + progress['progress_course'] = p.progress_status(sorted_token_list) + res.append(progress) + return Response(res, status=200) + except ValidationError: + return Response("Bad request", status=400) + + return Response(status=403) + + +class UploadCourseProgressUserView(APIView): + renderer_classes = (JSONRenderer,) + + @staticmethod + def get(request, token): + if request.user.is_authenticated() and request.user.is_staff: + try: + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="%s.csv"' % token + sorted_token_list = CourseProgressApi.get_topic_lesson(token) + writer = csv.writer(response) + writer.writerow(['Имя', 'Почта', 'Последняя тема', 'Последний урок']) + + for p in Progress.objects.filter(course_token=token): + progress = ProgressAnalyticSerializer(p).data + progress['progress_course'] = p.progress_status(sorted_token_list) + writer.writerow([ + progress['name'], + progress['email'], + progress['progress_course'] and progress['progress_course'][0], + progress['progress_course'] and progress['progress_course'][1], + ]) + return response + except ValidationError: + return Response("Bad request", status=400) + return Response(status=403)