diff --git a/access/views.py b/access/views.py index 5915943..f698ae0 100644 --- a/access/views.py +++ b/access/views.py @@ -28,7 +28,10 @@ class TeacherListView(APIView): status_code = 200 def get(self, request): - return Response([i.email for i in get_user_model().objects.filter(groups__name='teachers')], self.status_code) + return Response([{ + 'email': i.email, + 'token': i.out_key, + } for i in get_user_model().objects.filter(groups__name='teachers')], self.status_code) class ResetPasswordView(APIView): diff --git a/courses/models.py b/courses/models.py index 3bc61ac..ce50bf7 100755 --- a/courses/models.py +++ b/courses/models.py @@ -58,8 +58,6 @@ class Lesson(models.Model): class Topic(models.Model): course = models.ForeignKey(to="Course", verbose_name='курс') title = models.CharField(verbose_name='Название', max_length=255) - description = models.TextField(verbose_name='Описание', blank=True, null=True) - icon = models.ImageField(verbose_name='Иконка темы', null=True, blank=True) sort = models.SmallIntegerField(verbose_name='Поле сортировки') def __str__(self): @@ -75,12 +73,12 @@ class Topic(models.Model): class CourseManager(models.Manager): def update_or_create_course(self, image=None, big_image=None, statistic=None, - big_mobile_image=None, slug=None, teachers=None, + big_mobile_image=None, slug=None, teacher_tokens=None, level=None, direction=None, **kwargs): slug = slug if slug else slugify(unidecode.unidecode(kwargs['title'])) - kwargs['teacher_tokens'] = teachers + kwargs['teacher_tokens'] = teacher_tokens if image: path = 'course/image%s.png' % slug @@ -101,7 +99,7 @@ class CourseManager(models.Manager): kwargs['level'] = get_real_name(COURSE_LEVEL, level) if direction: - kwargs['direction'] = get_real_name(COURSE_DIRECTION, direction) + kwargs['direction'] = get_real_name(COURSE_DIRECTION, direction[0]) try: course = self.get(slug=slug) diff --git a/courses/urls.py b/courses/urls.py index 819f814..3c78dbf 100644 --- a/courses/urls.py +++ b/courses/urls.py @@ -7,5 +7,7 @@ urlpatterns = [ url(r'lesson/(?P.+)/$', views.LessonDetail.as_view()), url(r'tree/(?P.+)/$', views.TreeView.as_view()), url(r'detail/(?P.+)/$', views.CourseDetailView.as_view()), + url(r'topic/update/$', views.UpdateTopicView.as_view()), + url(r'topic/delete/(?P[0-9]{1,99})/$', views.DeleteTopicView.as_view()), url(r'^$', views.CourseListView.as_view()), ] \ No newline at end of file diff --git a/courses/views.py b/courses/views.py index 5db4617..0b7f74e 100644 --- a/courses/views.py +++ b/courses/views.py @@ -1,17 +1,19 @@ +from django.db.models import F from jwt import DecodeError -from courses.models import Course, Lesson +from courses.models import Course, Lesson, Topic from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView from django.contrib.auth import get_user_model -from courses.serializers import CourseDetailSerializer, CourseTreeSerializer, LessonSerializer, TeacherLessonSerializer +from courses.serializers import CourseDetailSerializer, CourseTreeSerializer, LessonSerializer, TeacherLessonSerializer, \ + TopicSerializer import jwt from courses.tasks import add_lesson from lms import settings - +import json class TreeView(APIView): renderer_classes = (JSONRenderer,) @@ -31,27 +33,6 @@ class CourseListView(APIView): status_code = 200 def post(self, request): - """ - This API endpoint create/update course. - --- - parameters: - - name: level - type: string - required: true - location: form - - name: direction - type: string - required: true - location: form - - name: statistic - type: string - required: true - location: form - ... - """ - # TODO: Костыль - teachers_emails = request.JSON.get('teachers', []) - request.JSON['teachers'] = [get_user_model().objects.get(email=i).out_key for i in teachers_emails] course = Course.objects.update_or_create_course(**request.JSON.dict()) return Response(CourseDetailSerializer(course).data, status=self.status_code) @@ -80,6 +61,69 @@ class CourseDetailView(APIView): return Response(CourseDetailSerializer(Course.objects.get(slug=slug)).data, self.status_code) +class DeleteTopicView(APIView): + renderer_classes = (JSONRenderer,) + + @staticmethod + def delete(request, topic_id): + try: + t = Topic.objects.get(id=topic_id) + except Topic.DoesNotExist: + return Response("Темы не существует", status=404) + t.delete() + return Response(CourseTreeSerializer(t.course).data, status=200) + + +class UpdateTopicView(APIView): + renderer_classes = (JSONRenderer,) + + @staticmethod + def post(request): + topic_id = request.JSON.get('id', None) + sort = request.JSON.get('sort', None) + course_token = request.JSON.get('course_token', None) + title = request.JSON.get('title', None) + + if course_token is None: + return Response("Не передан course_token", status=400) + + if sort is None: + return Response("Не передан sort", status=400) + + try: + course = Course.objects.get(token=course_token) + except Course.DoesNotExist: + return Response("Курс не найден", status=404) + + try: + if topic_id: + t = Topic.objects.get(id=topic_id) + if not t.sort == sort: + for topic in reversed(): + topic.sort = topic.sort + 1 + topic.save() + t.sort = sort + t.title = t.title if title is None else title + t.save() + else: + raise Topic.DoesNotExist() + + except Topic.DoesNotExist: + if title is None: + return Response("Не передан title", status=400) + + for topic in reversed(course.topic_set.filter(sort__gte=sort)): + topic.sort = topic.sort + 1 + topic.save() + + Topic.objects.create( + course=course, + title=title, + sort=sort, + ) + return Response(CourseTreeSerializer(course).data, status=200) + + class LessonInfoView(APIView): renderer_classes = (JSONRenderer,) status_code = 200 @@ -109,7 +153,7 @@ class LessonDetail(APIView): l = LessonSerializer(lesson).data try: - payload = None if jwt_token is None\ + payload = None if jwt_token is None \ else jwt.decode(jwt_token, settings.COURSE_PROGRESS_SECRET_KEY, algorithms=['HS256']) except DecodeError: payload = None @@ -144,7 +188,7 @@ class LessonDetail(APIView): if not new_lesson: return Response("Permission denied", status=403) - #TODO Задача для селери + # TODO Задача для селери add_lesson(request.user.out_key, course.token, lesson.token, course.get_teacher(), lesson.is_hm) return Response(l, status=200) diff --git a/finance/views.py b/finance/views.py index 507c5fa..494d022 100644 --- a/finance/views.py +++ b/finance/views.py @@ -97,6 +97,9 @@ class InvoiceDetailView(APIView): except (Bill.DoesNotExist, KeyError): return Response('Bill id must be set', status=400) + invoice_data['method'] = get_real_name(elem=invoice_data['method'], array=Invoice.BILL_METHOD) + invoice_data['status'] = get_real_name(elem=invoice_data['status'], array=Invoice.BILL_METHOD) + if bill.check_validate() and invoice_data['is_open']: return Response("Уже есть платёж открывающий курс", status=400)