From afb70f10d9b2589477a5b4e488ea1d461d8f64b6 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 1 Dec 2017 23:14:21 +0300 Subject: [PATCH] create map --- access/admin.py | 3 +- access/migrations/0001_initial.py | 4 +- access/models/__init__.py | 6 ++ access/models/other.py | 68 +++++++++++++++++++++ access/{models.py => models/user.py} | 84 ++------------------------ access/serializers.py | 43 ++++++------- access/views.py | 13 ++-- courses/serializers.py | 19 +++--- courses/views.py | 31 +++------- csv/load_courses.py | 15 ++--- csv/load_perm.py | 2 +- csv/load_student_teachers_threads.py | 2 +- csv/load_users.py | 2 +- finance/signals.py | 2 +- journals/default_threads.py | 3 + journals/views.py | 2 +- maps/migrations/0005_coursemap_name.py | 20 ++++++ maps/models.py | 49 +++++++++++---- maps/serializers.py | 22 +++++-- 19 files changed, 216 insertions(+), 174 deletions(-) create mode 100755 access/models/__init__.py create mode 100644 access/models/other.py rename access/{models.py => models/user.py} (62%) mode change 100755 => 100644 create mode 100644 maps/migrations/0005_coursemap_name.py diff --git a/access/admin.py b/access/admin.py index 90663a2..90fc21e 100755 --- a/access/admin.py +++ b/access/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin -from access.models import Progress, User, Account, Invite +from access.models.other import Invite, Account, Progress +from access.models.user import User admin.site.register(User) admin.site.register(Account) diff --git a/access/migrations/0001_initial.py b/access/migrations/0001_initial.py index be411b3..5b51025 100644 --- a/access/migrations/0001_initial.py +++ b/access/migrations/0001_initial.py @@ -5,6 +5,8 @@ from __future__ import unicode_literals import access.models from django.db import migrations, models +import access.models.user + class Migration(migrations.Migration): @@ -34,7 +36,7 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Пользователи', }, managers=[ - ('objects', access.models.CustomUserManager()), + ('objects', access.models.user.CustomUserManager()), ], ), migrations.CreateModel( diff --git a/access/models/__init__.py b/access/models/__init__.py new file mode 100755 index 0000000..b2288a5 --- /dev/null +++ b/access/models/__init__.py @@ -0,0 +1,6 @@ +# encoding=utf-8 + +from .other import Account, Progress, Invite +from .user import User + + diff --git a/access/models/other.py b/access/models/other.py new file mode 100644 index 0000000..b774feb --- /dev/null +++ b/access/models/other.py @@ -0,0 +1,68 @@ +from django.conf import settings +from django.db import models + +from courses.models import Course, Vertex +from maps.models import CourseRoute + + +class Invite(models.Model): + owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, null=True) + hash = models.CharField(max_length=15) + date = models.DateTimeField(null=True, blank=True) + + class Meta: + verbose_name = 'Приглошение в систему' + verbose_name_plural = 'Приглошения в систему' + + +class Account(models.Model): + GENDER_CHOICES = ( + (0, 'undefined'), + (1, 'male'), + (2, 'female'), + ) + b_day = models.DateField(blank=True, null=True) + city = models.CharField(max_length=63, null=True, blank=True) + gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0) + owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, null=True) + photo = models.ImageField(null=True, blank=True, default='/static/default/access/default.png', upload_to='user/photo/') + phone = models.CharField(max_length=15, null=True, blank=True) + + def __str__(self): + return self.owner.email + + class Meta: + verbose_name = 'Дополнительная информация о пользователе' + verbose_name_plural = 'Дополнительная информация о пользователе' + + +class Progress(models.Model): + user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент', null=True) + course = models.ForeignKey(to=Course, verbose_name='Курс', null=True) + progress_list = models.ManyToManyField(to=Vertex, verbose_name='Лист пройденных объектов', blank=True) + template = models.OneToOneField(to=CourseRoute, blank=True, null=True, verbose_name='Шаблон для прохождения если ' + 'не указан явно смотри ' + 'функцию get_template()') + + def __str__(self): + return '%s %s' % ( + self.user.email, + self.course.title, + ) + + def get_template(self): + return self.template if self.template else self.course.route + + def is_finish(self): + return self.get_template().is_finish(self.user) + + def get_objects_in_progress(self): + return self.get_template().get_active_objects(self.user) + + def is_access(self, vertex): + return vertex in self.progress_list.all() or vertex == self.get_objects_in_progress() + + class Meta: + verbose_name = 'Прогресс пользователя' + verbose_name_plural = 'Прогресс пользователя' + unique_together = (("user", "course"),) \ No newline at end of file diff --git a/access/models.py b/access/models/user.py old mode 100755 new mode 100644 similarity index 62% rename from access/models.py rename to access/models/user.py index cab5f68..6c261be --- a/access/models.py +++ b/access/models/user.py @@ -1,56 +1,16 @@ -# encoding=utf-8 import random import string -from django.contrib.contenttypes.models import ContentType -from django_celery_results.models import TaskResult - -from courses.models import Vertex, Course -from maps.models import CourseMap, CourseRoute -from storage.models import Storage +from django.contrib.auth.base_user import BaseUserManager, AbstractBaseUser +from django.contrib.auth.models import Group, PermissionsMixin from django.core.mail import send_mail - -from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager -from django.contrib.auth.models import PermissionsMixin, Group - from django.db import models - -from django.conf import settings from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from lms.global_decorators import transaction_decorator -from journals.models import Journal, Thread, ACTION_CHOICES - -class Invite(models.Model): - owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, null=True) - hash = models.CharField(max_length=15) - date = models.DateTimeField(null=True, blank=True) - - class Meta: - verbose_name = 'Приглошение в систему' - verbose_name_plural = 'Приглошения в систему' - - -class Account(models.Model): - GENDER_CHOICES = ( - (0, 'undefined'), - (1, 'male'), - (2, 'female'), - ) - b_day = models.DateField(blank=True, null=True) - city = models.CharField(max_length=63, null=True, blank=True) - gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0) - owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, null=True) - photo = models.ImageField(null=True, blank=True, default='/static/default/access/default.png', upload_to='user/photo/') - phone = models.CharField(max_length=15, null=True, blank=True) - - def __str__(self): - return self.owner.email - - class Meta: - verbose_name = 'Дополнительная информация о пользователе' - verbose_name_plural = 'Дополнительная информация о пользователе' +from access.models.other import Invite, Account +from journals.models import Thread +from lms.global_decorators import transaction_decorator class CustomUserManager(BaseUserManager): @@ -170,36 +130,4 @@ class User(AbstractBaseUser, PermissionsMixin): class Meta: verbose_name = _('Пользователь') - verbose_name_plural = _('Пользователи') - - -class Progress(models.Model): - user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент', null=True) - course = models.ForeignKey(to=Course, verbose_name='Курс', null=True) - progress_list = models.ManyToManyField(to=Vertex, verbose_name='Лист пройденных объектов', blank=True) - template = models.OneToOneField(to=CourseRoute, blank=True, null=True, verbose_name='Шаблон для прохождения если ' - 'не указан явно смотри ' - 'функцию get_template()') - - def __str__(self): - return '%s %s' % ( - self.user.email, - self.course.title, - ) - - def get_template(self): - return self.template if self.template else self.course.route - - def is_finish(self): - return self.get_template().is_finish(self.user) - - def get_objects_in_progress(self): - return self.get_template().get_active_objects(self.user) - - def is_access(self, vertex): - return vertex in self.progress_list - - class Meta: - verbose_name = 'Прогресс пользователя' - verbose_name_plural = 'Прогресс пользователя' - unique_together = (("user", "course"),) + verbose_name_plural = _('Пользователи') \ No newline at end of file diff --git a/access/serializers.py b/access/serializers.py index 2a90dcc..aabb38f 100644 --- a/access/serializers.py +++ b/access/serializers.py @@ -1,36 +1,36 @@ from django.contrib.auth import get_user_model from rest_framework import serializers -from access.models import Account, Progress -from maps.serializers import CourseRouteSerializer +from access.models.other import Account, Progress +from courses.serializers import MiniVertexSerializer, CourseInitSerializer class ProgressSerializer(serializers.ModelSerializer): - template = serializers.SerializerMethodField() - course = serializers.SerializerMethodField() max = serializers.SerializerMethodField() number = serializers.SerializerMethodField() + in_progress = serializers.SerializerMethodField() + course = serializers.SerializerMethodField() class Meta: model = Progress - fields = ('course', 'template', 'number', 'max', 'progress_list', ) + fields = ('in_progress', 'number', 'max', 'progress_list', 'course') @staticmethod def get_max(self): return self.course.get_vertexes('topic').count() @staticmethod - def get_number(self): - if self.is_finish(): - return self.get_max() - return self.progress_list.filter(content_type__model="topic").count() + def get_course(self): + return CourseInitSerializer(self.course).data @staticmethod - def get_course(self): - return {'title': self.course.title, 'slug': self.course.slug} + def get_in_progress(self): + return [MiniVertexSerializer(i).data for i in self.get_objects_in_progress()] @staticmethod - def get_template(self): - return CourseRouteSerializer(self.get_template()).data + def get_number(self): + if self.is_finish(): + return self.get_max() + return self.progress_list.filter(content_type__model="topic").count() class AccountSerializer(serializers.ModelSerializer): @@ -45,13 +45,15 @@ class AccountSerializer(serializers.ModelSerializer): return self.get_gender_display() -class UserInitSerializer(serializers.ModelSerializer): +class UserSelfSerializer(serializers.ModelSerializer): account = serializers.SerializerMethodField() groups = serializers.SerializerMethodField() + progress = serializers.SerializerMethodField() class Meta: model = get_user_model() - fields = ('id', 'email', 'first_name', 'last_name', 'account', 'groups', 'is_staff', 'is_superuser') + fields = ('id', 'email', 'first_name', 'last_name','progress', + 'account', 'groups', 'is_staff', 'is_superuser') @staticmethod def get_account(self): @@ -61,23 +63,22 @@ class UserInitSerializer(serializers.ModelSerializer): def get_groups(self): return [group.name for group in self.groups.all()] + @staticmethod + def get_progress(self): + return [ProgressSerializer(i).data for i in self.progress_set.all()] + class UserProfileSerializer(serializers.ModelSerializer): account = serializers.SerializerMethodField() groups = serializers.SerializerMethodField() - progress = serializers.SerializerMethodField() class Meta: model = get_user_model() fields = ( - 'id', 'email', 'first_name', 'last_name','progress', + 'id', 'email', 'first_name', 'last_name', 'account', 'groups', 'is_staff', 'is_superuser', ) - @staticmethod - def get_progress(self): - return [ProgressSerializer(i).data for i in self.progress_set.all()] - @staticmethod def get_account(self): return AccountSerializer(self.account).data diff --git a/access/views.py b/access/views.py index 4bf10bc..f5e5742 100644 --- a/access/views.py +++ b/access/views.py @@ -7,8 +7,8 @@ from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from django.db.models import Q -from access.models import Invite, Progress -from access.serializers import UserInitSerializer, UserSearchSerializer, UserProfileSerializer +from access.models.other import Invite, Progress +from access.serializers import UserSelfSerializer, UserSearchSerializer, UserProfileSerializer from courses.models import Vertex from journals.models import Thread @@ -37,7 +37,7 @@ class InfoUserView(APIView): def get(self, request): if request.user.is_authenticated(): - return Response(UserInitSerializer(request.user).data, status=self.status_code) + return Response(UserSelfSerializer(request.user).data, status=self.status_code) return Response('anonymous', status=self.status_code) @@ -85,8 +85,7 @@ class DetailUserView(APIView): except get_user_model().DoesNotExist: return Response("User doesn't exist", status=404) - serialized_user = UserProfileSerializer(user).data - + serialized_user = UserSelfSerializer(user).data serialized_user['is_i'] = request.user == user return Response(serialized_user, status=200) @@ -126,7 +125,7 @@ class RegistrationView(APIView): email=request.JSON['email'].lower(), ) - return Response(UserInitSerializer(user).data, status=200) + return Response(UserSelfSerializer(user).data, status=200) class ChangePasswordView(APIView): @@ -152,7 +151,7 @@ class LoginView(APIView): auth.login(request, user) except AttributeError: return Response("Неверный пароль", status=404) - return Response(UserInitSerializer(request.user).data, status=200) + return Response(UserSelfSerializer(request.user).data, status=200) class LogoutView(APIView): diff --git a/courses/serializers.py b/courses/serializers.py index 95d6362..8d8ec5f 100644 --- a/courses/serializers.py +++ b/courses/serializers.py @@ -61,6 +61,13 @@ class VertexSerializer(MiniVertexSerializer): return False +class CourseInitSerializer(serializers.ModelSerializer): + + class Meta: + model = Course + fields = ['title', 'slug'] + + class CourseListSerializer(serializers.ModelSerializer): statistic = serializers.SerializerMethodField() level = serializers.SerializerMethodField() @@ -84,18 +91,6 @@ class CourseListSerializer(serializers.ModelSerializer): return self.get_direction_display() -class CourseTreeSerializer(serializers.ModelSerializer): - route = serializers.SerializerMethodField() - - class Meta: - model = Course - fields = ['id', 'route'] - - @staticmethod - def get_route(self): - return CourseRouteSerializer(self.route).data - - class CourseDetailSerializer(serializers.ModelSerializer): level = serializers.SerializerMethodField() direction = serializers.SerializerMethodField() diff --git a/courses/views.py b/courses/views.py index 9a6b97f..e9638bc 100644 --- a/courses/views.py +++ b/courses/views.py @@ -2,10 +2,9 @@ from rest_framework.views import APIView from rest_framework.renderers import JSONRenderer from rest_framework.response import Response -from access.serializers import ProgressSerializer +from maps.serializers import CourseMapSerializer from courses.models import Course, Vertex -from access.models import Progress -from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer, CourseTreeSerializer +from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer from journals.models import Thread @@ -25,21 +24,11 @@ class TreeView(APIView): except Course.DoesNotExist: return Response("Course doesn't exist", status=404) - res = CourseTreeSerializer(course).data + if request.user.is_authenticated(): + route = course.progress_set.get(user=request.user).get_template() + return Response(CourseMapSerializer(route.get_first()).data, self.status_code) - if not request.user.is_authenticated(): - res['active_id'] = False - res['extra_privilege'] = [] - return Response(res, self.status_code) - - try: - res['progress'] = ProgressSerializer( - Progress.objects.get(course=course, user=request.user) - ).data - except Progress.DoesNotExist: - res['progress'] = False - - return Response(res, self.status_code) + return Response(CourseMapSerializer(course.route.get_first()).data, self.status_code) class CourseDetailView(APIView): @@ -69,14 +58,8 @@ class CourseListView(APIView): course_list = Course.objects.all() else: course_list = Course.objects.filter(public=True) - res = [] - for course in course_list: - course_serialize = CourseListSerializer(course).data - course_serialize['is_mine'] = False - if request.user.is_authenticated() and Progress.objects.filter(course=course, user=request.user).exists(): - course_serialize['is_mine'] = True - res.append(course_serialize) + res = [CourseListSerializer(course).data for course in course_list] return Response(res, self.status_code) diff --git a/csv/load_courses.py b/csv/load_courses.py index 8740719..5f9ab4f 100644 --- a/csv/load_courses.py +++ b/csv/load_courses.py @@ -36,11 +36,11 @@ if __name__ == '__main__': except IntegrityError: pass - # with open('./course/storage.csv') as storage_csv: - # storage_reader = csv.DictReader(storage_csv) - # for row in storage_reader: - # if row['original']: - # Storage.objects.get_or_create(**row) + with open('./course/storage.csv') as storage_csv: + storage_reader = csv.DictReader(storage_csv) + for row in storage_reader: + if row['original']: + Storage.objects.get_or_create(**row) with open('./course/vertex.csv') as vertex_csv: vertex_reader = csv.DictReader(vertex_csv) @@ -59,8 +59,6 @@ if __name__ == '__main__': sort = 0 for vertex in Vertex.objects.filter(course=course, content_type__model='topic').order_by("object_id"): - PivotVertex.objects.create(map_course=map_obj, vertex=vertex, sort=sort) - sort += 1 for small_vertex in Vertex.objects.filter(course=course, content_type__model='tutorial', vertex=vertex).order_by("object_id"): PivotVertex.objects.create(map_course=map_obj, vertex=small_vertex, sort=sort) sort += 1 @@ -68,6 +66,9 @@ if __name__ == '__main__': PivotVertex.objects.create(map_course=map_obj, vertex=small_vertex, sort=sort) sort += 1 + PivotVertex.objects.create(map_course=map_obj, vertex=vertex, sort=sort) + sort += 1 + PivotCourseMap.objects.create(map_course=map_obj, route=route_obj, sort=0) course.save() diff --git a/csv/load_perm.py b/csv/load_perm.py index 9fe861a..a5ce220 100644 --- a/csv/load_perm.py +++ b/csv/load_perm.py @@ -5,7 +5,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") django.setup() from django.contrib.auth import get_user_model -from access.models import Progress +from access.models.other import Progress from courses.models import Vertex, Course if __name__ == '__main__': diff --git a/csv/load_student_teachers_threads.py b/csv/load_student_teachers_threads.py index bf65906..6cf2dfb 100644 --- a/csv/load_student_teachers_threads.py +++ b/csv/load_student_teachers_threads.py @@ -30,7 +30,7 @@ if __name__ == '__main__': child_thread, is_create = Thread.objects.get_or_create( key="""user_%s__vertex_%s""" % (user.id, vertex.id,), - text="""Домашняя работа по курсу %s и теме %s для студента %s""" % + text="""%s - %s - %s""" % (vertex.course.title, vertex.vertex_set.all()[0].title, user.get_full_name()), ) diff --git a/csv/load_users.py b/csv/load_users.py index 7ad84dc..c55f73d 100644 --- a/csv/load_users.py +++ b/csv/load_users.py @@ -5,7 +5,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") django.setup() from django.contrib.auth import get_user_model -from access.models import Account +from access.models.other import Account if __name__ == '__main__': with open('./access/users.csv') as user_csv: diff --git a/finance/signals.py b/finance/signals.py index 9e362bc..629f328 100644 --- a/finance/signals.py +++ b/finance/signals.py @@ -4,7 +4,7 @@ from django.dispatch import receiver from yandex_money.models import Payment from finance.models import Invoice -from access.models import Progress +from access.models.other import Progress @receiver(pre_save, sender=Invoice) diff --git a/journals/default_threads.py b/journals/default_threads.py index 8de1ef4..d50c4fe 100644 --- a/journals/default_threads.py +++ b/journals/default_threads.py @@ -67,6 +67,9 @@ def main_threads(): managers.groups.add(Group.objects.get(name='managers')) managers.parent.add(lead_managers) + for user in get_user_model().objects.all(): + Thread.objects.get_or_create(key="""user_%s""" % user.id) + if __name__ == '__main__': main_threads() diff --git a/journals/views.py b/journals/views.py index 07ddd49..b2bbc73 100644 --- a/journals/views.py +++ b/journals/views.py @@ -6,7 +6,7 @@ from rest_framework.response import Response import csv from django.http import HttpResponse, HttpResponseForbidden -from access.models import Progress +from access.models.other import Progress from journals.models import Thread, Journal from journals.serilizers import ThreadDetailSerializer, ThreadAdminSerializer, JournalSerializer from lms.tools import decode_base64 diff --git a/maps/migrations/0005_coursemap_name.py b/maps/migrations/0005_coursemap_name.py new file mode 100644 index 0000000..34989b9 --- /dev/null +++ b/maps/migrations/0005_coursemap_name.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-12-01 20:12 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('maps', '0004_auto_20171129_1447'), + ] + + operations = [ + migrations.AddField( + model_name='coursemap', + name='name', + field=models.CharField(default='Линейное прохождение', max_length=255, verbose_name='Имя прохождения'), + ), + ] diff --git a/maps/models.py b/maps/models.py index 0b3cc15..78351ac 100644 --- a/maps/models.py +++ b/maps/models.py @@ -16,11 +16,14 @@ class CourseRoute(models.Model): return bool(sum([int(i.map_course.is_finish(user)) for i in self.pivotcoursemap_set.all()])) def get_active_objects(self, user): - return (i.map_course.getactive_object(user) for i in self.pivotcoursemap_set.all()) + return (i.map_course.get_active_object(user) for i in self.pivotcoursemap_set.all()) def get_maps(self): return (i.map_course for i in self.pivotcoursemap_set.all()) + def get_first(self): + return self.pivotcoursemap_set.first().map_course + def __str__(self): return self.name @@ -34,10 +37,11 @@ class CourseMap(models.Model): Способы отображения курса. Упорядочены в порядке возрастания приоретета. """ course = models.ForeignKey(to='courses.Course', verbose_name='К какому курсу привязан') + name = models.CharField(max_length=255, verbose_name="Имя прохождения", default="Линейное прохождение") @transaction_decorator def add_vertex(self, vertex, sort): - if sort > self.pivotvertex_set.count()+1: + if sort > self.pivotvertex_set.count() + 1: raise ValueError("list index out of range") for i in self.pivotvertex_set.filter(sort__gte=sort): i.sort += 1 @@ -48,23 +52,42 @@ class CourseMap(models.Model): return pivot def get_objects(self, vertex=None): - if not self.course == vertex.course: + if vertex and not self.course == vertex.course: raise MapTypeError('''Переданный узел принадлежит курсу "%s", а должен принадлежать курсу "%s"''' - % (self.course.title, vertex.course.title)) + % (self.course.title, vertex.course.title)) + full_list = [i.vertex for i in self.pivotvertex_set.all()] + if vertex: - return full_list[:full_list.index(vertex)+1] + return full_list[:full_list.index(vertex) + 1] + return full_list + def get_tree(self, serializer=None): + from courses.serializers import MiniVertexSerializer + serializer = serializer if serializer is not None else MiniVertexSerializer + + def helper(v_list): + new_list = [] + for i in v_list: + val = serializer(i).data + new_list.append(val) + if i.children.all().count(): + val['children'] = helper(i.children.all()) + return new_list + + return helper([i.vertex for i in self.pivotvertex_set.filter(vertex__vertex__isnull=True)]) + def get_difference(self, user) -> list: return list(set([i.vertex for i in self.pivotvertex_set.all()]) - .difference(set(user.progress_set.get(course=self.course).progress_list.all()))) + .difference(set(user.progress_set.get(course=self.course).progress_list.all()))) def is_finish(self, user) -> bool: return self.get_difference(user) == [] def get_active_object(self, user): - return self.pivotvertex_set.exclude(vertex__in=self.get_difference(user))[0] + return self.pivotvertex_set.exclude(vertex__in=self.get_difference(user), vertex__content_type__model='topic')[ + 0].vertex def __str__(self): return '''Линейное прохождение по курсу "%s"''' % self.course.title @@ -77,7 +100,8 @@ class CourseMap(models.Model): class PivotCourseMap(models.Model): route = models.ForeignKey(to=CourseRoute, verbose_name="К какому узлу") sort = models.SmallIntegerField(verbose_name='Порядок сортировки') - map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, null=True) + map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, + null=True) def __str__(self): return '''Карта с №%s по маршруту ID%s''' % (self.sort, self.route_id) @@ -85,14 +109,15 @@ class PivotCourseMap(models.Model): class Meta: verbose_name = 'Порядок сортировки маршрута' verbose_name_plural = 'Порядки сортировок маршрутов' - unique_together = (('map_course', 'route'), ('sort', 'route'), ) - ordering = ('sort', ) + unique_together = (('map_course', 'route'), ('sort', 'route'),) + ordering = ('sort',) class PivotVertex(models.Model): vertex = models.ForeignKey(to='courses.Vertex', verbose_name="К какому узлу") sort = models.SmallIntegerField(verbose_name='Порядок сортировки') - map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, null=True) + map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, + null=True) def __str__(self): return '''Карта с №%s по линейному прохождению ID%s''' % (self.sort, self.map_course_id) @@ -101,4 +126,4 @@ class PivotVertex(models.Model): verbose_name = 'Порядок сортировки узла' verbose_name_plural = 'Порядки сортировок узла' unique_together = (('map_course', 'vertex'), ('sort', 'map_course')) - ordering = ('sort', ) + ordering = ('sort',) diff --git a/maps/serializers.py b/maps/serializers.py index 93b9e21..d620793 100644 --- a/maps/serializers.py +++ b/maps/serializers.py @@ -8,20 +8,30 @@ class CourseRouteSerializer(serializers.ModelSerializer): class Meta: model = CourseRoute - fields = '__all__' + fields = ('maps', 'name') @staticmethod def get_maps(self): - return [CourseMapSerializer(i).data for i in self.get_maps()] + return [CourseMapSerializer(i).data for i in self.get_maps()][0] class CourseMapSerializer(serializers.ModelSerializer): - vertexes = serializers.SerializerMethodField() + tree = serializers.SerializerMethodField() + course_slug = serializers.SerializerMethodField() + map_name = serializers.SerializerMethodField() class Meta: model = CourseMap - fields = '__all__' + fields = ('tree', 'course_slug', 'map_name') @staticmethod - def get_vertexes(self): - return [i.id for i in self.pivotvertex_set.all()] \ No newline at end of file + def get_tree(self): + return self.get_tree() + + @staticmethod + def get_course_slug(self): + return self.course.slug + + @staticmethod + def get_map_name(self): + return self.name \ No newline at end of file