parent
af4261f409
commit
b42a589c28
24 changed files with 364 additions and 285 deletions
@ -1,11 +1,4 @@ |
|||||||
#**SkillBox LMS** |
#**SkillBox LMS** |
||||||
|
|
||||||
Нужно выполнить миграции и запустить скрипт update_db.py без параметров в модуле courses (скрипт на всякий случай пока не удалять) |
DROP TABLE courses_normalmap; |
||||||
|
снести табличку вручную |
||||||
Фактически в структуре данных изменилось только то, что появилась новая табличка NormalMap. Скрипт собирает все treeview курсов и кладёт в эту табличку |
|
||||||
|
|
||||||
Появилась новая зависимость django_rest_framework. |
|
||||||
|
|
||||||
Изменения никак не трогают старый функционал. |
|
||||||
|
|
||||||
Имеет смысл пробежаться по middl |
|
||||||
@ -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