You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

137 lines
5.8 KiB

from django.db import models
from lms.global_decorators import transaction_decorator
from maps.exeptions import MapTypeError
from django.db.models import Q
class CourseRoute(models.Model):
"""
Объединение нескольких мап курса, одназначно
определяет способ прохождения по курсу.
"""
name = models.CharField(max_length=255, verbose_name='Имя шаблона', blank=True, null=True, unique=True)
is_template = models.BooleanField(default=True, verbose_name='Может ли быть использован как шаблон')
def is_finish(self, user):
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.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
class Meta:
verbose_name = 'Маршрут прохождения'
verbose_name_plural = 'Маршруты прохождения'
class CourseMap(models.Model):
"""
Способы отображения курса. Упорядочены в порядке возрастания приоретета.
"""
course = models.ForeignKey(to='courses.Course', verbose_name='К какому курсу привязан')
name = models.CharField(max_length=255, verbose_name="Имя прохождения", default="Линейное прохождение")
def get_next(self, vertex):
next_idx = self.pivotvertex_set.get(vertex=vertex).sort + 1
return self.pivotvertex_set.get(sort=next_idx).vertex
@transaction_decorator
def add_vertex(self, vertex, sort):
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
i.save()
pivot = PivotVertex.objects.create(vertex=vertex, sort=sort, map_course=self)
pivot.save()
return pivot
def get_objects(self, vertex=None):
if vertex and not self.course == vertex.course:
raise MapTypeError('''Переданный узел принадлежит курсу "%s", а должен принадлежать курсу "%s"'''
% (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
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:
success_list = user.progress_set.get(course=self.course).progress_list.all()
all_vertex = [i.vertex for i in self.pivotvertex_set.all()]
res = list(set(all_vertex).difference(set(success_list)))
return res
def is_finish(self, user) -> bool:
return self.get_difference(user) == []
def get_active_object(self, user):
return self.pivotvertex_set.exclude(
vertex__content_type__model='topic'
).filter(vertex__in=self.get_difference(user)).first().vertex
def __str__(self):
return '''Линейное прохождение по курсу "%s"''' % self.course.title
class Meta:
verbose_name = 'Карта линейного прохождения курсов'
verbose_name_plural = 'Карты линейного прохождения курсов'
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)
def __str__(self):
return '''Карта с №%s по маршруту ID%s''' % (self.sort, self.route_id)
class Meta:
verbose_name = 'Порядок сортировки маршрута'
verbose_name_plural = 'Порядки сортировок маршрутов'
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)
def __str__(self):
return '''Карта с №%s по линейному прохождению ID%s''' % (self.sort, self.map_course_id)
class Meta:
verbose_name = 'Порядок сортировки узла'
verbose_name_plural = 'Порядки сортировок узла'
unique_together = (('map_course', 'vertex'), ('sort', 'map_course'))
ordering = ('sort',)