parent
af4261f409
commit
b42a589c28
24 changed files with 364 additions and 285 deletions
@ -1,11 +1,4 @@ |
||||
#**SkillBox LMS** |
||||
|
||||
Нужно выполнить миграции и запустить скрипт update_db.py без параметров в модуле courses (скрипт на всякий случай пока не удалять) |
||||
|
||||
Фактически в структуре данных изменилось только то, что появилась новая табличка NormalMap. Скрипт собирает все treeview курсов и кладёт в эту табличку |
||||
|
||||
Появилась новая зависимость django_rest_framework. |
||||
|
||||
Изменения никак не трогают старый функционал. |
||||
|
||||
Имеет смысл пробежаться по middl |
||||
DROP TABLE courses_normalmap; |
||||
снести табличку вручную |
||||
@ -0,0 +1,80 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-09-25 18:29 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
import django.db.models.manager |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('storage', '0002_auto_20160831_1638'), |
||||
('contenttypes', '0002_remove_content_type_name'), |
||||
('courses', '0045_auto_20170918_0811'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='NormalMap', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('dependent_elements', models.TextField(default='[]')), |
||||
('independent_elements', models.TextField(default='[]')), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='Task', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('is_exam', models.BooleanField(default=False, verbose_name='Экзамен или домашка')), |
||||
('materials', models.ManyToManyField(blank=True, to='storage.Storage', verbose_name='Материалы для домашней работы')), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='Topic', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('icon', models.ImageField(blank=True, null=True, upload_to='CourseTheme', verbose_name='Иконка темы')), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='Tutorial', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('on_comment', models.BooleanField(default=True, verbose_name='Комментарии')), |
||||
('video', models.TextField(blank=True, default='', verbose_name='Код видео')), |
||||
('materials', models.ManyToManyField(blank=True, to='storage.Storage', verbose_name='Материалы урока')), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='Vertex', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('title', models.CharField(max_length=255, verbose_name='Название')), |
||||
('description', models.TextField(blank=True, default='', null=True, verbose_name='Описание')), |
||||
('object_id', models.PositiveIntegerField()), |
||||
('children', models.ManyToManyField(blank=True, to='courses.Vertex')), |
||||
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), |
||||
], |
||||
managers=[ |
||||
('manager', django.db.models.manager.Manager()), |
||||
], |
||||
), |
||||
migrations.AlterField( |
||||
model_name='course', |
||||
name='level', |
||||
field=models.CharField(choices=[('B', 'Базовый'), ('A', 'Продвинутый'), ('E', 'Экспертный'), ('B+A', 'Базовый + Продвинутый')], default='B', max_length=3, verbose_name='Уровень'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='vertex', |
||||
name='course', |
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='normalmap', |
||||
name='course', |
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'), |
||||
), |
||||
] |
||||
@ -1,29 +0,0 @@ |
||||
# -*- 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'), |
||||
), |
||||
] |
||||
@ -1,22 +0,0 @@ |
||||
import os, sys |
||||
import django, json |
||||
|
||||
sys.path.append("../") |
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") |
||||
django.setup() |
||||
|
||||
from courses.models import Course, NormalMap, CourseTheme, Lesson, Homework, Exam |
||||
|
||||
if __name__ == '__main__': |
||||
for course in Course.objects.all(): |
||||
tree = [] |
||||
for theme in CourseTheme.objects.filter(course=course).order_by('sort'): |
||||
tree.append({'id': theme.id, 'body': |
||||
[str(i.id) + "_L" for i in Lesson.objects.filter(theme=theme).order_by('sort')] + |
||||
[str(i.id) + "_H" for i in Homework.objects.filter(theme=theme).order_by('sort')] + |
||||
[str(i.id) + "_E" for i in Exam.objects.filter(theme=theme).order_by('sort')] |
||||
}) |
||||
|
||||
obj, _is_create = NormalMap.objects.get_or_create(course=course) |
||||
obj.json_tree = json.dumps(tree) |
||||
obj.save() |
||||
@ -0,0 +1,58 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-09-25 18:29 |
||||
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'), |
||||
('journals', '0073_auto_20170918_0811'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='Action', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('name', models.CharField(max_length=255, verbose_name='Наименование действия (на английском)')), |
||||
('text', models.TextField(verbose_name='Описание действия')), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='Journal', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('object_id', models.PositiveIntegerField()), |
||||
('date', models.DateTimeField(auto_now=True)), |
||||
('action_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Action')), |
||||
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='Thread', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('key', models.CharField(max_length=200)), |
||||
('text', models.TextField(default='', verbose_name='Описание треда')), |
||||
('is_staff', models.BooleanField(default=False, verbose_name='Админская ли табличка')), |
||||
('parent', models.ManyToManyField(blank=True, related_name='_thread_parent_+', to='journals.Thread')), |
||||
('subscribers', models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Подписчики')), |
||||
], |
||||
), |
||||
migrations.AddField( |
||||
model_name='journal', |
||||
name='thread', |
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Thread', verbose_name='Тред'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='journal', |
||||
name='user', |
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Инициатор действия'), |
||||
), |
||||
] |
||||
@ -1,25 +0,0 @@ |
||||
# -*- 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='Описание треда'), |
||||
), |
||||
] |
||||
@ -1,20 +0,0 @@ |
||||
# -*- 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='Видно ли в админке'), |
||||
), |
||||
] |
||||
@ -1,20 +0,0 @@ |
||||
# -*- 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,7 @@ |
||||
from django.conf.urls import url |
||||
from journals import new_view as views |
||||
|
||||
urlpatterns = [ |
||||
url(r'thread/$', views.ThreadListView.as_view()), |
||||
url(r'thread/([0-9]{1,99})/$', views.ThreadDetailView.as_view()), |
||||
] |
||||
@ -0,0 +1,34 @@ |
||||
from rest_framework.views import APIView |
||||
from rest_framework.renderers import JSONRenderer |
||||
from rest_framework.response import Response |
||||
|
||||
from journals.models import Thread |
||||
from journals.serilizers import ThreadSerializer |
||||
|
||||
|
||||
class ThreadListView(APIView): |
||||
renderer_classes = (JSONRenderer,) |
||||
status_code = 200 |
||||
|
||||
def get(self, request): |
||||
return Response( |
||||
[ThreadSerializer(thread).data for thread in Thread.objects.filter(is_staff=True)], |
||||
self.status_code, |
||||
) |
||||
|
||||
|
||||
class ThreadDetailView(APIView): |
||||
renderer_classes = (JSONRenderer,) |
||||
status_code = 200 |
||||
|
||||
def post(self, request, pk): |
||||
try: |
||||
thread = Thread.objects.get(id=pk) |
||||
thread.text = request.JSON.get('text', thread.text) |
||||
thread.key = request.JSON.get('key', thread.key) |
||||
thread.x = request.JSON.get('x', thread.x) |
||||
thread.y = request.JSON.get('y', thread.y) |
||||
thread.save() |
||||
return Response(ThreadSerializer(thread).data, self.status_code,) |
||||
except Thread.DoesNotExist: |
||||
return Response("Thread doesn't exist.", self.status_code,) |
||||
@ -0,0 +1,10 @@ |
||||
from rest_framework import serializers |
||||
|
||||
from journals.models import Thread |
||||
|
||||
|
||||
class ThreadSerializer(serializers.ModelSerializer): |
||||
|
||||
class Meta: |
||||
model = Thread |
||||
exclude = ['is_staff'] |
||||
Loading…
Reference in new issue