feature/fix_generate_pass
Andrey 8 years ago
parent 01b6d3b5fe
commit 14ad75259b
  1. 2
      access/migrations/0001_initial.py
  2. 65
      access/migrations/0002_auto_20171128_1150.py
  3. 3
      access/models.py
  4. 0
      achievements/__init__.py
  5. 9
      achievements/admin.py
  6. 5
      achievements/apps.py
  7. 73
      achievements/migrations/0001_initial.py
  8. 56
      achievements/migrations/0002_auto_20171128_1518.py
  9. 0
      achievements/migrations/__init__.py
  10. 66
      achievements/models.py
  11. 3
      achievements/tests.py
  12. 3
      achievements/views.py
  13. 11
      courses/admin.py
  14. 149
      courses/migrations/0001_initial.py
  15. 143
      courses/models.py
  16. 6
      finance/migrations/0001_initial.py
  17. 6
      journals/migrations/0001_initial.py
  18. 2
      journals/models.py
  19. 2
      library/migrations/0001_initial.py
  20. 2
      lms/settings.py
  21. 0
      maps/__init__.py
  22. 6
      maps/admin.py
  23. 5
      maps/apps.py
  24. 77
      maps/migrations/0001_initial.py
  25. 0
      maps/migrations/__init__.py
  26. 86
      maps/models.py
  27. 3
      maps/tests.py
  28. 3
      maps/views.py
  29. 2
      storage/migrations/0001_initial.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50 # Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals from __future__ import unicode_literals
import access.models import access.models

@ -1,65 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0008_alter_user_username_max_length'),
('access', '0001_initial'),
('courses', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='progress',
name='course',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='Курс'),
),
migrations.AddField(
model_name='progress',
name='progress_list',
field=models.ManyToManyField(blank=True, to='courses.Vertex', verbose_name='Лист пройденных объектов'),
),
migrations.AddField(
model_name='progress',
name='template',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.CourseRoute', verbose_name='Шаблон для прохождения если не указан явно смотри функцию get_template()'),
),
migrations.AddField(
model_name='progress',
name='user',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент'),
),
migrations.AddField(
model_name='invite',
name='owner',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='account',
name='owner',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='user',
name='groups',
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'),
),
migrations.AddField(
model_name='user',
name='user_permissions',
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
),
migrations.AlterUniqueTogether(
name='progress',
unique_together=set([('user', 'course')]),
),
]

@ -5,7 +5,8 @@ import string
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django_celery_results.models import TaskResult from django_celery_results.models import TaskResult
from courses.models import Vertex, Course, CourseMap, CourseRoute from courses.models import Vertex, Course
from maps.models import CourseMap, CourseRoute
from storage.models import Storage from storage.models import Storage
from django.core.mail import send_mail from django.core.mail import send_mail

@ -0,0 +1,9 @@
from django.contrib import admin
from achievements.models import Skills, Achievements, SkillJ, DiplomaGen, Diploma
admin.site.register(Skills)
admin.site.register(Achievements)
admin.site.register(SkillJ)
admin.site.register(Diploma)
admin.site.register(DiplomaGen)

@ -0,0 +1,5 @@
from django.apps import AppConfig
class AchievementsConfig(AppConfig):
name = 'achievements'

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Achievements',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('icon', models.ImageField(blank=True, null=True, upload_to='diplomas', verbose_name='Отображение достижения')),
],
options={
'verbose_name': 'Достижение',
'verbose_name_plural': 'Достижения',
},
),
migrations.CreateModel(
name='Diploma',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('icon', models.ImageField(upload_to='diplomas', verbose_name='Иконка')),
],
options={
'verbose_name': 'Диплом',
'verbose_name_plural': 'Дипломы',
},
),
migrations.CreateModel(
name='DiplomaGen',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template', models.URLField(verbose_name='Путь до шаблона')),
],
options={
'verbose_name': 'Генератор дипломов',
'verbose_name_plural': 'Генераторы дипловов',
},
),
migrations.CreateModel(
name='SkillJ',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'verbose_name': 'Размер навыка',
'verbose_name_plural': 'Размеры навыков',
},
),
migrations.CreateModel(
name='Skills',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='Наименование')),
('color', models.CharField(max_length=255, verbose_name='Цвет')),
('icon', models.ImageField(help_text='65x65', null=True, upload_to='skills', verbose_name='Большая картинка')),
('description', models.TextField(blank=True, verbose_name='Описание')),
],
options={
'verbose_name': 'Навык',
'verbose_name_plural': 'Навыки',
},
),
]

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('achievements', '0001_initial'),
('courses', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='skillj',
name='lesson',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='Урок'),
),
migrations.AddField(
model_name='skillj',
name='skill',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='achievements.Skills', verbose_name='Навык'),
),
migrations.AddField(
model_name='diplomagen',
name='course',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'),
),
migrations.AddField(
model_name='diploma',
name='template',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='achievements.DiplomaGen', verbose_name='Использовать шаблон'),
),
migrations.AddField(
model_name='diploma',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='achievements',
name='course',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'),
),
migrations.AddField(
model_name='achievements',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

@ -0,0 +1,66 @@
from django.db import models
from django.conf import settings
from courses.models import Course, Vertex
class Achievements(models.Model):
course = models.ForeignKey(to=Course)
icon = models.ImageField(verbose_name='Отображение достижения', upload_to='diplomas', blank=True, null=True)
user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
def __str__(self):
return 'Студенту %s за курс %s' % (self.user.username, self.course.title)
class Meta:
verbose_name = 'Достижение'
verbose_name_plural = 'Достижения'
class Skills(models.Model):
title = models.CharField(verbose_name='Наименование', max_length=255)
color = models.CharField(verbose_name='Цвет', max_length=255)
icon = models.ImageField(verbose_name='Большая картинка', upload_to='skills', null=True, help_text='65x65')
description = models.TextField(verbose_name='Описание', blank=True)
def __str__(self): return '%s' % self.title
class Meta:
verbose_name = 'Навык'
verbose_name_plural = 'Навыки'
class SkillJ(models.Model):
skill = models.ForeignKey(to=Skills, verbose_name='Навык')
lesson = models.ForeignKey(to=Vertex, verbose_name='Урок')
def __str__(self): return '%s' % self.skill
class Meta:
verbose_name = 'Размер навыка'
verbose_name_plural = 'Размеры навыков'
class DiplomaGen(models.Model):
course = models.ForeignKey(to=Course)
template = models.URLField(verbose_name="Путь до шаблона")
def __str__(self):
return 'Шаблон можно найти по адресу: %s, диплом выдаётся за курс %s' % (self.template, self.course.title)
class Meta:
verbose_name = 'Генератор дипломов'
verbose_name_plural = 'Генераторы дипловов'
class Diploma(models.Model):
icon = models.ImageField(verbose_name='Иконка', upload_to='diplomas')
template = models.ForeignKey(to=DiplomaGen, verbose_name='Использовать шаблон', blank=True, null=True)
user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
def __str__(self):
return 'Студенту %s за курс %s' % (self.user.username, self.template.course.title)
class Meta:
verbose_name = 'Диплом'
verbose_name_plural = 'Дипломы'

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

@ -1,16 +1,9 @@
from django.contrib import admin from django.contrib import admin
from courses.models import Course, Skills, Achievements, SkillJ,\ from courses.models import Course, Tutorial, Topic, Task, Vertex
CourseMap, Topic, Task, Vertex, Diploma, Tutorial, DiplomaGen
admin.site.register(CourseMap)
admin.site.register(Topic) admin.site.register(Topic)
admin.site.register(Task) admin.site.register(Task)
admin.site.register(Vertex) admin.site.register(Vertex)
admin.site.register(Tutorial) admin.site.register(Tutorial)
admin.site.register(Course) admin.site.register(Course)
admin.site.register(Skills)
admin.site.register(Achievements)
admin.site.register(SkillJ)
admin.site.register(Diploma)
admin.site.register(DiplomaGen)

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50 # Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
@ -12,23 +12,12 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('storage', '0001_initial'), ('storage', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
] ]
operations = [ operations = [
migrations.CreateModel(
name='Achievements',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('icon', models.ImageField(blank=True, null=True, upload_to='diplomas', verbose_name='Отображение достижения')),
],
options={
'verbose_name': 'Достижение',
'verbose_name_plural': 'Достижения',
},
),
migrations.CreateModel( migrations.CreateModel(
name='Course', name='Course',
fields=[ fields=[
@ -37,6 +26,7 @@ class Migration(migrations.Migration):
('level', models.CharField(choices=[('B', 'Базовый'), ('A', 'Продвинутый'), ('E', 'Экспертный'), ('B+A', 'Базовый + Продвинутый')], default='B', max_length=3, verbose_name='Уровень')), ('level', models.CharField(choices=[('B', 'Базовый'), ('A', 'Продвинутый'), ('E', 'Экспертный'), ('B+A', 'Базовый + Продвинутый')], default='B', max_length=3, verbose_name='Уровень')),
('slug', models.SlugField(blank=True, default='', editable=False, max_length=255, unique=True)), ('slug', models.SlugField(blank=True, default='', editable=False, max_length=255, unique=True)),
('direction', models.SmallIntegerField(choices=[(3, 'Бизнес'), (2, 'Веб-дизайн'), (1, 'Разработка'), (4, 'Рисование')], null=True, verbose_name='Направление')), ('direction', models.SmallIntegerField(choices=[(3, 'Бизнес'), (2, 'Веб-дизайн'), (1, 'Разработка'), (4, 'Рисование')], null=True, verbose_name='Направление')),
('sort', models.SmallIntegerField(null=True, verbose_name='Порядок сортировки')),
('public', models.BooleanField(default=False, verbose_name='Опубликовать')), ('public', models.BooleanField(default=False, verbose_name='Опубликовать')),
('title', models.CharField(max_length=255, verbose_name='Заголовок')), ('title', models.CharField(max_length=255, verbose_name='Заголовок')),
('description', models.TextField(blank=True, verbose_name='Описание')), ('description', models.TextField(blank=True, verbose_name='Описание')),
@ -50,90 +40,6 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'Курсы', 'verbose_name_plural': 'Курсы',
}, },
), ),
migrations.CreateModel(
name='CourseMap',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='К какому курсу привязан')),
],
options={
'verbose_name': 'Карта линейного прохождения курсов',
'verbose_name_plural': 'Карты линейного прохождения курсов',
},
),
migrations.CreateModel(
name='CourseRoute',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=255, null=True, unique=True, verbose_name='Имя шаблона')),
('is_template', models.BooleanField(default=True, verbose_name='Может ли быть использован как шаблон')),
('maps', models.ManyToManyField(to='courses.CourseMap', verbose_name='Карта линейного прохождения курсов')),
],
options={
'verbose_name': 'Маршрут прохождения',
'verbose_name_plural': 'Маршруты прохождения',
},
),
migrations.CreateModel(
name='Diploma',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('icon', models.ImageField(upload_to='diplomas', verbose_name='Иконка')),
],
options={
'verbose_name': 'Диплом',
'verbose_name_plural': 'Дипломы',
},
),
migrations.CreateModel(
name='DiplomaGen',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template', models.URLField(verbose_name='Путь до шаблона')),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course')),
],
options={
'verbose_name': 'Генератор дипломов',
'verbose_name_plural': 'Генераторы дипловов',
},
),
migrations.CreateModel(
name='PivotVertex',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort', models.SmallIntegerField(unique=True, verbose_name='Порядок сортировки')),
('map_course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.CourseMap', verbose_name='К какой сортеровке имеетотношение')),
],
options={
'verbose_name': 'Порядок сортировки узла',
'verbose_name_plural': 'Порядки сортировок узла',
'ordering': ('sort',),
},
),
migrations.CreateModel(
name='SkillJ',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'verbose_name': 'Размер навыка',
'verbose_name_plural': 'Размеры навыков',
},
),
migrations.CreateModel(
name='Skills',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='Наименование')),
('color', models.CharField(max_length=255, verbose_name='Цвет')),
('icon', models.ImageField(help_text='65x65', null=True, upload_to='skills', verbose_name='Большая картинка')),
('description', models.TextField(blank=True, verbose_name='Описание')),
],
options={
'verbose_name': 'Навык',
'verbose_name_plural': 'Навыки',
},
),
migrations.CreateModel( migrations.CreateModel(
name='Task', name='Task',
fields=[ fields=[
@ -171,53 +77,4 @@ class Migration(migrations.Migration):
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course')),
], ],
), ),
migrations.AddField(
model_name='skillj',
name='lesson',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='Урок'),
),
migrations.AddField(
model_name='skillj',
name='skill',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Skills', verbose_name='Навык'),
),
migrations.AddField(
model_name='pivotvertex',
name='vertex',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='К какому узлу'),
),
migrations.AddField(
model_name='diploma',
name='template',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.DiplomaGen', verbose_name='Использовать шаблон'),
),
migrations.AddField(
model_name='diploma',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='course',
name='route',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.CourseRoute', verbose_name='Порядок прохождения по умолчанию'),
),
migrations.AddField(
model_name='course',
name='teachers',
field=models.ManyToManyField(related_name='course_teachers', to=settings.AUTH_USER_MODEL, verbose_name='Преподаватели'),
),
migrations.AddField(
model_name='achievements',
name='course',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'),
),
migrations.AddField(
model_name='achievements',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='pivotvertex',
unique_together=set([('map_course', 'vertex')]),
),
] ]

@ -8,6 +8,7 @@ from django.core.exceptions import ObjectDoesNotExist
import json import json
import unidecode import unidecode
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from maps.models import CourseRoute, CourseMap
from lms.tools import decode_base64, get_real_name from lms.tools import decode_base64, get_real_name
from lms.global_decorators import transaction_decorator from lms.global_decorators import transaction_decorator
@ -80,6 +81,7 @@ class Course(models.Model):
level = models.CharField(verbose_name='Уровень', choices=COURSE_LEVEL, default='B', max_length=3) level = models.CharField(verbose_name='Уровень', choices=COURSE_LEVEL, default='B', max_length=3)
slug = models.SlugField(max_length=255, blank=True, default='', unique=True, editable=False) slug = models.SlugField(max_length=255, blank=True, default='', unique=True, editable=False)
direction = models.SmallIntegerField(choices=COURSE_DIRECTION, verbose_name='Направление', null=True) direction = models.SmallIntegerField(choices=COURSE_DIRECTION, verbose_name='Направление', null=True)
sort = models.SmallIntegerField(null=True, verbose_name="Порядок сортировки")
mentors = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Кураторы', blank=True, mentors = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Кураторы', blank=True,
related_name='course_mentors') related_name='course_mentors')
public = models.BooleanField(verbose_name='Опубликовать', default=False) public = models.BooleanField(verbose_name='Опубликовать', default=False)
@ -91,7 +93,7 @@ class Course(models.Model):
help_text='Большая картинка для мобильной версии', max_length=255) help_text='Большая картинка для мобильной версии', max_length=255)
teachers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Преподаватели', teachers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Преподаватели',
related_name='course_teachers') related_name='course_teachers')
route = models.OneToOneField(to="CourseRoute", verbose_name="Порядок прохождения по умолчанию", blank=True, null=True) route = models.OneToOneField(to=CourseRoute, verbose_name="Порядок прохождения по умолчанию", blank=True, null=True)
def __str__(self): def __str__(self):
return self.title return self.title
@ -99,6 +101,13 @@ class Course(models.Model):
def get_teacher(self): def get_teacher(self):
return random.choice(self.teachers.all()) return random.choice(self.teachers.all())
def get_map(self, user):
route = self.route
if user.is_authenticated:
route = user.progress_set.get(course=self).get_template()
map_list = route.get_sorted_maps()
return self.route.maps.all()[0]
def get_tree(self, serializer): def get_tree(self, serializer):
""" """
Способ отображения дочерних элементов. Способ отображения дочерних элементов.
@ -171,70 +180,8 @@ class Course(models.Model):
objects = CourseManager() objects = CourseManager()
class Meta: class Meta:
verbose_name = u"Курс" verbose_name = "Курс"
verbose_name_plural = u"Курсы" verbose_name_plural = "Курсы"
class Skills(models.Model):
title = models.CharField(verbose_name='Наименование', max_length=255)
color = models.CharField(verbose_name='Цвет', max_length=255)
icon = models.ImageField(verbose_name='Большая картинка', upload_to='skills', null=True, help_text='65x65')
description = models.TextField(verbose_name='Описание', blank=True)
def __str__(self): return '%s' % self.title
class Meta:
verbose_name = 'Навык'
verbose_name_plural = 'Навыки'
class SkillJ(models.Model):
skill = models.ForeignKey(to="Skills", verbose_name='Навык')
lesson = models.ForeignKey(to="Vertex", verbose_name='Урок')
def __str__(self): return '%s' % self.skill
class Meta:
verbose_name = 'Размер навыка'
verbose_name_plural = 'Размеры навыков'
class Achievements(models.Model):
course = models.ForeignKey(to="Course")
icon = models.ImageField(verbose_name='Отображение достижения', upload_to='diplomas', blank=True, null=True)
user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
def __str__(self):
return 'Студенту %s за курс %s' % (self.user.username, self.course.title)
class Meta:
verbose_name = 'Достижение'
verbose_name_plural = 'Достижения'
class DiplomaGen(models.Model):
course = models.ForeignKey(to=Course)
template = models.URLField(verbose_name="Путь до шаблона")
def __str__(self):
return 'Шаблон можно найти по адресу: %s, диплом выдаётся за курс %s' % (self.template, self.course.title)
class Meta:
verbose_name = 'Генератор дипломов'
verbose_name_plural = 'Генераторы дипловов'
class Diploma(models.Model):
icon = models.ImageField(verbose_name='Иконка', upload_to='diplomas')
template = models.ForeignKey(to=DiplomaGen, verbose_name='Использовать шаблон', blank=True, null=True)
user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
def __str__(self):
return 'Студенту %s за курс %s' % (self.user.username, self.template.course.title)
class Meta:
verbose_name = 'Диплом'
verbose_name_plural = 'Дипломы'
class VertexManager(models.Manager): class VertexManager(models.Manager):
@ -397,69 +344,3 @@ class Topic(models.Model):
Возможно поле icon перекачует в Vertex, а данная модель отвалится за ненадобностью Возможно поле icon перекачует в Vertex, а данная модель отвалится за ненадобностью
""" """
icon = models.ImageField(verbose_name='Иконка темы', null=True, blank=True) icon = models.ImageField(verbose_name='Иконка темы', null=True, blank=True)
class CourseRoute(models.Model):
"""
Объединение нескольких мап курса, одназначно
определяет способ прохождения по курсу.
"""
name = models.CharField(max_length=255, verbose_name='Имя шаблона', blank=True, null=True, unique=True)
maps = models.ManyToManyField(to="CourseMap", verbose_name="Карта линейного прохождения курсов")
is_template = models.BooleanField(default=True, verbose_name='Может ли быть использован как шаблон')
def is_finish(self, user):
return bool(sum([int(i.is_finish(user)) for i in self.maps.all()]))
def get_active_objects(self, user):
return [i.getactive_object(user) for i in self.maps.all()]
class Meta:
verbose_name = 'Маршрут прохождения'
verbose_name_plural = 'Маршруты прохождения'
class CourseMap(models.Model):
"""
Способы отображения курса. Упорядочены в порядке возрастания приоретета.
"""
course = models.ForeignKey(to=Course, verbose_name='К какому курсу привязан')
@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_difference(self, user) -> list:
return list(set(
[i.vertex for i in self.pivotvertex_set.all()]).difference(set(user.progress.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]
class Meta:
verbose_name = 'Карта линейного прохождения курсов'
verbose_name_plural = 'Карты линейного прохождения курсов'
class PivotVertex(models.Model):
vertex = models.ForeignKey(to=Vertex, verbose_name="К какому узлу")
sort = models.SmallIntegerField(verbose_name='Порядок сортировки', unique=True)
map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, null=True)
class Meta:
verbose_name = 'Порядок сортировки узла'
verbose_name_plural = 'Порядки сортировок узла'
unique_together = (('map_course', 'vertex'),)
ordering = ('sort', )

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50 # Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
@ -12,9 +12,9 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('yandex_money', '0001_initial'), ('yandex_money', '0002_auto_20171128_1150'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('courses', '0001_initial'), ('courses', '0002_auto_20171128_1518'),
] ]
operations = [ operations = [

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50 # Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
@ -12,10 +12,10 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('auth', '0008_alter_user_username_max_length'),
('contenttypes', '0002_remove_content_type_name'),
('storage', '0001_initial'), ('storage', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('auth', '0008_alter_user_username_max_length'),
('contenttypes', '0002_remove_content_type_name'),
] ]
operations = [ operations = [

@ -8,7 +8,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db import connection from django.db import connection
from courses.models import Achievements, Course, CourseMap, Diploma from courses.models import Course
from finance.models import Bill from finance.models import Bill
from storage.models import Storage from storage.models import Storage

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50 # Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime

@ -111,6 +111,8 @@ apps = (
'finance', 'finance',
'journals', 'journals',
'library', 'library',
'achievements',
'maps',
'config_app', 'config_app',
) )

@ -0,0 +1,6 @@
from django.contrib import admin
from maps.models import CourseMap, CourseRoute
admin.site.register(CourseMap)
admin.site.register(CourseRoute)

@ -0,0 +1,5 @@
from django.apps import AppConfig
class MapsConfig(AppConfig):
name = 'maps'

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('courses', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='CourseMap',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='К какому курсу привязан')),
],
options={
'verbose_name': 'Карта линейного прохождения курсов',
'verbose_name_plural': 'Карты линейного прохождения курсов',
},
),
migrations.CreateModel(
name='CourseRoute',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=255, null=True, unique=True, verbose_name='Имя шаблона')),
('is_template', models.BooleanField(default=True, verbose_name='Может ли быть использован как шаблон')),
],
options={
'verbose_name': 'Маршрут прохождения',
'verbose_name_plural': 'Маршруты прохождения',
},
),
migrations.CreateModel(
name='PivotCourseMap',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort', models.SmallIntegerField(unique=True, verbose_name='Порядок сортировки')),
('map_course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='maps.CourseMap', verbose_name='К какой сортеровке имеетотношение')),
('route', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='maps.CourseRoute', verbose_name='К какому узлу')),
],
options={
'verbose_name': 'Порядок сортировки узла',
'verbose_name_plural': 'Порядки сортировок узла',
'ordering': ('sort',),
},
),
migrations.CreateModel(
name='PivotVertex',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort', models.SmallIntegerField(unique=True, verbose_name='Порядок сортировки')),
('map_course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='maps.CourseMap', verbose_name='К какой сортеровке имеетотношение')),
('vertex', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='К какому узлу')),
],
options={
'verbose_name': 'Порядок сортировки узла',
'verbose_name_plural': 'Порядки сортировок узла',
'ordering': ('sort',),
},
),
migrations.AlterUniqueTogether(
name='pivotvertex',
unique_together=set([('map_course', 'vertex')]),
),
migrations.AlterUniqueTogether(
name='pivotcoursemap',
unique_together=set([('map_course', 'route')]),
),
]

@ -0,0 +1,86 @@
from django.db import models
from lms.global_decorators import transaction_decorator
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.getactive_object(user) for i in self.pivotcoursemap_set.all())
def get_view(self):
return (i.map_course for i in self.pivotcoursemap_set.all())
class Meta:
verbose_name = 'Маршрут прохождения'
verbose_name_plural = 'Маршруты прохождения'
class CourseMap(models.Model):
"""
Способы отображения курса. Упорядочены в порядке возрастания приоретета.
"""
course = models.ForeignKey(to='courses.Course', verbose_name='К какому курсу привязан')
@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 merge(self, another):
return # TODO: Доделать!!!
def get_difference(self, user) -> list:
return list(set(
[i.vertex for i in self.pivotvertex_set.all()]).difference(set(user.progress.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]
class Meta:
verbose_name = 'Карта линейного прохождения курсов'
verbose_name_plural = 'Карты линейного прохождения курсов'
class PivotCourseMap(models.Model):
route = models.ForeignKey(to=CourseRoute, verbose_name="К какому узлу")
sort = models.SmallIntegerField(verbose_name='Порядок сортировки', unique=True)
map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, null=True)
class Meta:
verbose_name = 'Порядок сортировки узла'
verbose_name_plural = 'Порядки сортировок узла'
unique_together = (('map_course', 'route'),)
ordering = ('sort', )
class PivotVertex(models.Model):
vertex = models.ForeignKey(to='courses.Vertex', verbose_name="К какому узлу")
sort = models.SmallIntegerField(verbose_name='Порядок сортировки', unique=True)
map_course = models.ForeignKey(to=CourseMap, verbose_name='К какой сортеровке имеетотношение', blank=True, null=True)
class Meta:
verbose_name = 'Порядок сортировки узла'
verbose_name_plural = 'Порядки сортировок узла'
unique_together = (('map_course', 'vertex'),)
ordering = ('sort', )

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-28 11:50 # Generated by Django 1.11.6 on 2017-11-28 15:18
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

Loading…
Cancel
Save