Менеджер узлов

feature/fix_generate_pass
Andrey 8 years ago
parent 14824738b2
commit af4261f409
  1. 0
      access/access_update.py
  2. 22
      access/migrations/0091_privilege.py
  3. 28
      access/migrations/0092_auto_20170921_1707.py
  4. 6
      access/models.py
  5. 26
      courses/admin.py
  6. 5
      courses/apps.py
  7. 75
      courses/course_update.py
  8. 29
      courses/migrations/0047_auto_20170921_1746.py
  9. 79
      courses/models.py
  10. 9
      courses/signals.py
  11. 6
      finance/models.py
  12. 9
      journals/admin.py
  13. 40
      journals/default_threads.py
  14. 25
      journals/migrations/0076_auto_20170922_1116.py
  15. 20
      journals/migrations/0077_auto_20170922_1117.py
  16. 20
      journals/migrations/0078_auto_20170922_1118.py
  17. 24
      journals/migrations/0079_auto_20170922_1123.py
  18. 23
      journals/models.py
  19. 0
      journals/new_urls.py
  20. 0
      journals/new_view.py
  21. 1
      lms/settings.py
  22. 29
      reactions/migrations/0002_like.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-21 17:07
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('access', '0090_auto_20170918_0811'),
]
operations = [
migrations.CreateModel(
name='Privilege',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('value', models.CharField(choices=[('r', 'Отображение'), ('u', 'Использование'), ('w', 'Изменение')], default='r', max_length=1, verbose_name='Права')),
],
),
]

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-21 17:07
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):
dependencies = [
('access', '0091_privilege'),
('courses', '0046_auto_20170921_1707'),
]
operations = [
migrations.AddField(
model_name='privilege',
name='subject',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='Объект'),
),
migrations.AddField(
model_name='privilege',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Правообладатель'),
),
]

@ -630,9 +630,9 @@ class Questionnaire(models.Model):
class Privilege(models.Model):
TYPES = (
('r', 'Отображение'),
('u', 'Использование'),
('w', 'Изменение'),
('r', 'Доступно для выполнению'),
('w', 'Ждёт ответа'),
('d', 'Выполнено'),
)
user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name=u'Правообладатель')
value = models.CharField(verbose_name=u'Права', choices=TYPES, max_length=1, default='r')

@ -2,8 +2,14 @@ from django.contrib import admin
from access.models import User
from courses.models import Lesson, Course, CourseTheme, Homework, Exam, \
Skills, Achievements, SkillJ, CourseMap, \
AchievementsMap, Diploma, MaterialDirection, Flow
Skills, Achievements, SkillJ, CourseMap, NormalMap, Topic, Task, Vertex,\
AchievementsMap, Diploma, MaterialDirection, Tutorial
admin.site.register(NormalMap)
admin.site.register(Topic)
admin.site.register(Task)
admin.site.register(Vertex)
admin.site.register(Tutorial)
class LessonAdmin(admin.ModelAdmin):
@ -122,12 +128,12 @@ class DiplomaAdmin(admin.ModelAdmin):
admin.site.register(Diploma, DiplomaAdmin)
class FlowAdmin(admin.ModelAdmin):
save_on_top = True
list_display = ('title', 'course', 'start_flow')
raw_id_fields = ['course']
list_filter = ('start_flow','course')
search_fields = ['title', 'description']
admin.site.register(Flow, FlowAdmin)
# class FlowAdmin(admin.ModelAdmin):
# save_on_top = True
# list_display = ('title', 'course', 'start_flow')
# raw_id_fields = ['course']
# list_filter = ('start_flow','course')
# search_fields = ['title', 'description']
#
# admin.site.register(Flow, FlowAdmin)

@ -4,4 +4,7 @@ from django.apps import AppConfig
class CoursesAppConfig(AppConfig):
name = "courses"
verbose_name = "Курсы"
verbose_name = "Курсы"
def ready(self):
import courses.signals

@ -0,0 +1,75 @@
import os, sys
import django, json
sys.path.append("../")
os.environ['PG_PORT_5432_TCP_ADDR'] = '127.0.0.1'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from django.contrib.contenttypes.models import ContentType
from courses.models import Course, NormalMap, CourseTheme, Lesson, Homework, Exam, \
Tutorial, Task, Topic, Vertex
if __name__ == '__main__':
for course in Course.objects.all():
tree = []
for theme in CourseTheme.objects.filter(course=course).order_by('sort'):
topic_vertex = Vertex.manager.create_with_dependencies(
course=course,
title=theme.title,
description=theme.description,
model='topic',
icon=theme.icon,
)
tree.append(topic_vertex.id)
children = []
for i in Lesson.objects.filter(theme=theme).order_by('sort'):
on_comment = i.on_comment == 'N' or i.on_comment == 'T' and i.theme.on_comment
tutor = Tutorial.objects.create(video=i.video, on_comment=on_comment)
[tutor.materials.add(j) for j in i.materials.all()]
lesson_type = ContentType.objects.get(app_label="courses", model="tutorial")
vertex = Vertex.objects.create(
course=course,
title=i.title,
description=i.description,
content_type=lesson_type,
object_id=tutor.id,
)
topic_vertex.children.add(vertex)
children.append(vertex.id)
for i in Homework.objects.filter(theme=theme).order_by('sort'):
task = Task.objects.create(is_exam=False,)
[task.materials.add(j) for j in i.materials.all()]
task_type = ContentType.objects.get(app_label="courses", model="task")
vertex = Vertex.objects.create(
course=course,
title='Домашняя работа',
description=i.description,
content_type=task_type,
object_id=task.id,
)
topic_vertex.children.add(vertex)
children.append(vertex.id)
for i in Exam.objects.filter(theme=theme).order_by('sort'):
task=Task.objects.create(is_exam=True,)
[task.materials.add(j) for j in i.materials.all()]
task_type = ContentType.objects.get(app_label="courses", model="task")
vertex = Vertex.objects.create(
course=course,
title='Экзамен',
description=i.description,
content_type=task_type,
object_id=task.id,
)
topic_vertex.children.add(vertex)
children.append(vertex.id)
tree.append(children)
course_map, _is_create = NormalMap.objects.get_or_create(course=course)
course_map.json_tree=json.dumps(tree)
course_map.save()

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-21 17:46
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('courses', '0046_auto_20170921_1707'),
]
operations = [
migrations.CreateModel(
name='NormalMap',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('json_tree', models.TextField(default='')),
('independent_elements', models.TextField(default='')),
],
),
migrations.AddField(
model_name='normalmap',
name='course',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'),
),
]

@ -948,34 +948,34 @@ class CourseBuilder:
return self.token if self.material else None # Вернуть токен для материала если он есть
class Flow(models.Model):
title = models.CharField(verbose_name=u'Название', max_length=255)
description = models.TextField(
verbose_name=u'Описание', default='', blank=True, null=True)
course = models.ForeignKey(Course, verbose_name=u'Курс')
start_flow = models.DateTimeField(
verbose_name=u'Дата начала потока', default=datetime.datetime.now)
created = models.DateTimeField(
default=datetime.datetime.now, verbose_name=u"Создан", editable=False)
modified = models.DateTimeField(
auto_now=True, verbose_name=u"Изменен")
def __str__(self):
return '%s / %s' % (self.title, self.course)
def __unicode__(self):
return '%s / %s' % (self.title, self.course)
def get_status(self):
if self.start_flow <= datetime.datetime.now():
return True
else:
return False
class Meta:
verbose_name = u'Поток'
verbose_name_plural = u'Потоки'
ordering = ['-modified']
# class Flow(models.Model):
# title = models.CharField(verbose_name=u'Название', max_length=255)
# description = models.TextField(
# verbose_name=u'Описание', default='', blank=True, null=True)
# course = models.ForeignKey(Course, verbose_name=u'Курс')
# start_flow = models.DateTimeField(
# verbose_name=u'Дата начала потока', default=datetime.datetime.now)
# created = models.DateTimeField(
# default=datetime.datetime.now, verbose_name=u"Создан", editable=False)
# modified = models.DateTimeField(
# auto_now=True, verbose_name=u"Изменен")
#
# def __str__(self):
# return '%s / %s' % (self.title, self.course)
#
# def __unicode__(self):
# return '%s / %s' % (self.title, self.course)
#
# def get_status(self):
# if self.start_flow <= datetime.datetime.now():
# return True
# else:
# return False
#
# class Meta:
# verbose_name = u'Поток'
# verbose_name_plural = u'Потоки'
# ordering = ['-modified']
# Модели нового API со временем всё, что выше будет выпилено
@ -994,6 +994,21 @@ class Topic(models.Model):
icon = models.ImageField(verbose_name=u'Иконка темы', upload_to='CourseTheme', null=True, blank=True)
class VertexManager(models.Manager):
# Менеджер вершин графа. На самом деле
def create_with_dependencies(self, model, course, title, description, **kwargs):
content_type = ContentType.objects.get(app_label='courses', model=model)
obj = content_type.model_class().objects.create(**kwargs)
return self.create(
content_type=content_type,
object_id=obj.id,
course=course,
title=title,
description=description,
)
class Vertex(models.Model):
course = models.ForeignKey(to=Course)
title = models.CharField(verbose_name=u'Название', max_length=255)
@ -1004,6 +1019,14 @@ class Vertex(models.Model):
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
manager = VertexManager()
def __str__(self):
return self.title + ': ' + self.get_type()
def get_type(self):
return self.content_type.__str__()
class NormalMap(models.Model):
course = models.OneToOneField(to=Course)

@ -0,0 +1,9 @@
from django.db.models.signals import pre_delete
from django.dispatch import receiver
from courses.models import Vertex
@receiver(pre_delete, sender=Vertex)
def delete_dependencies(instance, **kwargs):
instance.content_object.delete()

@ -14,7 +14,7 @@ from management.letters import sent_created_my_self_bill, sent_new_my_self_bill,
pay_no_public_course, sent_new_service_request_to_out
from service.models import MailBox
from courses.models import Flow
#from courses.models import Flow
class Installment(models.Model):
@ -129,8 +129,8 @@ class Bill(models.Model):
help_text=u'Сумма, минус комиссия')
traf_source = models.ForeignKey(TrafHistory, verbose_name=u'Обращение', blank=True, null=True, editable=False)
service = models.ForeignKey(Price, verbose_name=u'Оплачиваемая услуга')
flow = models.ForeignKey(
Flow, verbose_name=u'Поток', blank=True, null=True)
# flow = models.ForeignKey(
# Flow, verbose_name=u'Поток', blank=True, null=True)
inside_data = models.TextField(verbose_name=u'Данные проверки', default='', blank=True, editable=False)
#
user = models.ForeignKey(User, verbose_name=u'Плательщик', related_name=u'bill_user')

@ -7,8 +7,13 @@ from django.http import HttpResponse
from access.models import User
from journals.models import TeacherJ, LessonJ, HomeworkJ, \
ExamJ, AchievementJ, HomeworkTry, \
ExamTry, CourseThemeJ, DiplomaJ, ReportDepth
from import_export.admin import ImportExportModelAdmin
ExamTry, CourseThemeJ, DiplomaJ, ReportDepth,\
Thread, Journal, Action
admin.site.register(Thread)
admin.site.register(Journal)
admin.site.register(Action)
def export_xls(modeladmin, request, queryset):

@ -0,0 +1,40 @@
import os, sys, django
sys.path.append("../")
os.environ['PG_PORT_5432_TCP_ADDR'] = '127.0.0.1'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from journals.models import Thread
from django.contrib.auth import get_user_model
if __name__ == '__main__':
support_list = [
'kate.gazukina@skillbox.ru',
'katerina.ragozina@skillbox.ru',
]
admin_list = [
'andrey.korolev@skillbox.ru',
'pavel.matveev@skillbox.ru',
]
admin_thread, _is_create = Thread.objects.get_or_create(
key='Admin',
text='Тред для админов сюда падают все журналируемые сообщения в системе',
is_staff=True,
)
for i in get_user_model().objects.filter(email__in=admin_list):
admin_thread.subscribers.add(i)
support_thread, _is_create = Thread.objects.get_or_create(
key='Support',
text='Тред сапортов занимаются поддержкой клиента',
is_staff=True,
)
support_thread.parent.add(admin_thread)
for i in get_user_model().objects.filter(email__in=support_list):
support_thread.subscribers.add(i)

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-22 11:16
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('journals', '0075_remove_journal_body'),
]
operations = [
migrations.AddField(
model_name='thread',
name='is_staff',
field=models.BooleanField(default=True, verbose_name='Видно ли в админке'),
),
migrations.AlterField(
model_name='thread',
name='text',
field=models.TextField(default='', verbose_name='Описание треда'),
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-22 11:17
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('journals', '0076_auto_20170922_1116'),
]
operations = [
migrations.AlterField(
model_name='thread',
name='is_staff',
field=models.BooleanField(default=False, verbose_name='Видно ли в админке'),
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-22 11:18
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('journals', '0077_auto_20170922_1117'),
]
operations = [
migrations.AlterField(
model_name='thread',
name='is_staff',
field=models.BooleanField(default=False, verbose_name='Админская ли табличка'),
),
]

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-22 11:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('journals', '0078_auto_20170922_1118'),
]
operations = [
migrations.RemoveField(
model_name='thread',
name='children',
),
migrations.AddField(
model_name='thread',
name='parent',
field=models.ManyToManyField(blank=True, related_name='_thread_parent_+', to='journals.Thread'),
),
]

@ -118,12 +118,6 @@ class TeacherJ(models.Model):
def get_head_face(self):
if self.start_date and self.student:
by = Bill.objects.filter(service__course=self.course, status='F', user=self.student)
flow_status = None
start_flow = None
if by.exists():
if by[0].flow:
flow_status = by[0].flow.get_status()
start_flow = by[0].flow.start_flow
return {
'title': self.course.get_title(),
'teacher': self.teacher,
@ -141,9 +135,6 @@ class TeacherJ(models.Model):
'page': self.course.page,
'course_id': self.course.id,
'by': by.exists(),
'by_type': '',
'by_flow': flow_status,
'by_start_flow': start_flow
}
else:
return self.get_empty_head_face()
@ -1682,7 +1673,6 @@ class Journal(models.Model):
thread = models.ForeignKey(to='Thread', verbose_name=u'Тред')
user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name=u'Инициатор действия')
content_type = models.ForeignKey(to=ContentType)
body = models.TextField(default='')
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
action_type = models.ForeignKey(to='Action')
@ -1694,14 +1684,21 @@ class Journal(models.Model):
class Thread(models.Model):
key = models.CharField(max_length=200)
text = models.TextField(verbose_name=u'Описание треда')
text = models.TextField(default='', verbose_name=u'Описание треда')
is_staff = models.BooleanField(default=False, verbose_name=u'Админская ли табличка')
subscribers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name=u'Подписчики')
children = models.ManyToManyField(to='self', blank=True)
parent = models.ManyToManyField(to='self', blank=True)
def get_journals(self, **filter_extra):
threads = [i for i in self.children.all()].append(self)
threads = [i for i in self.thread_set.all()].append(self)
return Journal.objects.filter(thread_in=threads, **filter_extra).order_by('-date')
def check_perm(self, user):
return (user in self.subscribers.all()) or bool(sum([int(i.check_perm(user)) for i in self.parent.all()]))
def __str__(self):
return self.key
class Action(models.Model):
name = models.CharField(max_length=255, verbose_name=u'Наименование действия (на английском)')

@ -92,6 +92,7 @@ INSTALLED_APPS = [
'library',
'practice',
'precise_bbcode',
'reactions',
]
MIDDLEWARE_CLASSES = [

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-09-21 17:58
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):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
('reactions', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Like',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_positive', models.BooleanField(default=True)),
('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Инициатор действия')),
],
),
]
Loading…
Cancel
Save