From 9ace79accd8ad1055f34b575c34b86fc99bc14b8 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 12 Jan 2018 16:57:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- access/admin.py | 8 +- access/migrations/0001_initial.py | 51 ++++--- .../0003_remove_progresslesson_comment.py | 19 --- access/migrations/0004_auto_20180112_1123.py | 25 ---- access/models/__init__.py | 3 +- access/models/other.py | 57 -------- access/models/progress.py | 62 ++++++++ access/serializers.py | 4 +- access/views.py | 4 +- achievements/migrations/0001_initial.py | 2 +- courses/admin.py | 7 +- courses/migrations/0001_initial.py | 86 +++++++----- courses/migrations/0002_init_demands.py | 16 +-- courses/migrations/0003_lesson_old_id.py | 20 +++ courses/models.py | 41 +++--- csv/load_bills.py | 2 +- csv/load_comments.py | 3 +- csv/load_courses.py | 132 +++++++++--------- csv/load_perm.py | 11 +- csv/load_users.py | 2 +- finance/migrations/0001_initial.py | 4 +- finance/migrations/0002_auto_20180112_1013.py | 20 --- library/migrations/0001_initial.py | 2 +- storage/migrations/0001_initial.py | 2 +- 24 files changed, 286 insertions(+), 297 deletions(-) delete mode 100644 access/migrations/0003_remove_progresslesson_comment.py delete mode 100644 access/migrations/0004_auto_20180112_1123.py create mode 100644 courses/migrations/0003_lesson_old_id.py delete mode 100644 finance/migrations/0002_auto_20180112_1013.py diff --git a/access/admin.py b/access/admin.py index 7693fe0..6b38215 100755 --- a/access/admin.py +++ b/access/admin.py @@ -1,5 +1,7 @@ from django.contrib import admin -from access.models.other import Invite, Account, Progress, ResetPassword, ProgressLesson, UserAnswer, UserAnswerBlock +from access.models.other import Invite, Account, ResetPassword +from access.models.progress import ProgressLesson, UserLessonAnswer, AnswerItem +from access.models import Progress from access.models.user import User admin.site.register(User) @@ -8,5 +10,5 @@ admin.site.register(Progress) admin.site.register(Invite) admin.site.register(ResetPassword) admin.site.register(ProgressLesson) -admin.site.register(UserAnswer) -admin.site.register(UserAnswerBlock) \ No newline at end of file +admin.site.register(AnswerItem) +admin.site.register(UserLessonAnswer) \ No newline at end of file diff --git a/access/migrations/0001_initial.py b/access/migrations/0001_initial.py index 159df44..fc35d65 100644 --- a/access/migrations/0001_initial.py +++ b/access/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-11 17:32 +# Generated by Django 1.11.6 on 2018-01-12 15:44 from __future__ import unicode_literals import access.models.user @@ -61,6 +61,20 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Дополнительная информация о пользователе', }, ), + migrations.CreateModel( + name='AnswerItem', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('question', models.TextField(verbose_name='Вопрос')), + ('value', models.TextField(verbose_name='Ответ')), + ('comment', models.TextField(blank=True, null=True, verbose_name='Комент')), + ('status', models.CharField(choices=[('done', 'done'), ('wait', 'wait'), ('fail', 'fail')], default='wait', max_length=20)), + ], + options={ + 'verbose_name': 'Ответ пользователя', + 'verbose_name_plural': 'Ответы пользователя', + }, + ), migrations.CreateModel( name='Invite', fields=[ @@ -78,7 +92,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('hidden_lessons', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, unique=True, verbose_name='Токен урока'), default=[], size=None, verbose_name='Список скрытых уроков')), - ('course_token', models.UUIDField(editable=False, unique=True, verbose_name='Токен курса')), + ('course_token', models.UUIDField(editable=False, verbose_name='Токен курса')), ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teacher_progress', to=settings.AUTH_USER_MODEL, verbose_name='Преподователь по умолчанию')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент')), ], @@ -91,8 +105,7 @@ class Migration(migrations.Migration): name='ProgressLesson', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('lesson_token', models.UUIDField(editable=False, unique=True, verbose_name='Токен урока')), - ('comment', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=15, unique=True, verbose_name='Ссылки на комменты'), default=[], size=None)), + ('lesson_token', models.UUIDField(editable=False, verbose_name='Токен урока')), ('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата зачтения задания')), ('progress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='access.Progress')), ('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Преподователь')), @@ -103,26 +116,12 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='UserAnswer', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('key', models.CharField(blank=True, max_length=255, verbose_name='Наименование поля')), - ('value', models.TextField(verbose_name='Значение в поле')), - ('status', models.CharField(choices=[('done', 'done'), ('wait', 'wait'), ('fail', 'fail')], default='done', max_length=20)), - ], - options={ - 'verbose_name': 'Ответ пользователя', - 'verbose_name_plural': 'Ответы пользователя', - }, - ), - migrations.CreateModel( - name='UserAnswerBlock', + name='UserLessonAnswer', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата сдачи')), - ('demand_token', models.UUIDField(editable=False, unique=True, verbose_name='Токен правила')), - ('checker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Проверяющий')), - ('progress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='access.ProgressLesson')), + ('progress_lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='access.ProgressLesson')), + ('reviewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Проверяющий')), ], options={ 'verbose_name': 'Блок ответов пользователя', @@ -141,16 +140,16 @@ class Migration(migrations.Migration): }, bases=('access.invite',), ), - migrations.AddField( - model_name='useranswer', - name='block', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='access.UserAnswerBlock'), - ), migrations.AddField( model_name='invite', name='owner', field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Кому приглошение'), ), + migrations.AddField( + model_name='answeritem', + name='lesson_answer', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='access.UserLessonAnswer'), + ), migrations.AlterUniqueTogether( name='progress', unique_together=set([('user', 'course_token')]), diff --git a/access/migrations/0003_remove_progresslesson_comment.py b/access/migrations/0003_remove_progresslesson_comment.py deleted file mode 100644 index c7627d5..0000000 --- a/access/migrations/0003_remove_progresslesson_comment.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-12 10:57 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('access', '0002_init_group'), - ] - - operations = [ - migrations.RemoveField( - model_name='progresslesson', - name='comment', - ), - ] diff --git a/access/migrations/0004_auto_20180112_1123.py b/access/migrations/0004_auto_20180112_1123.py deleted file mode 100644 index 9b9a3cf..0000000 --- a/access/migrations/0004_auto_20180112_1123.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-12 11:23 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('access', '0003_remove_progresslesson_comment'), - ] - - operations = [ - migrations.AlterField( - model_name='progress', - name='course_token', - field=models.UUIDField(editable=False, verbose_name='Токен курса'), - ), - migrations.AlterField( - model_name='progresslesson', - name='lesson_token', - field=models.UUIDField(editable=False, verbose_name='Токен урока'), - ), - ] diff --git a/access/models/__init__.py b/access/models/__init__.py index b2288a5..666ece4 100755 --- a/access/models/__init__.py +++ b/access/models/__init__.py @@ -1,6 +1,7 @@ # encoding=utf-8 -from .other import Account, Progress, Invite +from .other import Account, Invite +from access.models.progress import Progress from .user import User diff --git a/access/models/other.py b/access/models/other.py index ef28073..a3fdc7f 100644 --- a/access/models/other.py +++ b/access/models/other.py @@ -1,7 +1,5 @@ from django.conf import settings -from django.contrib.postgres.fields import ArrayField from django.db import models -from model_utils import Choices from phonenumber_field.modelfields import PhoneNumberField @@ -44,58 +42,3 @@ class Account(models.Model): verbose_name_plural = 'Дополнительная информация о пользователе' -class Progress(models.Model): - hidden_lessons = ArrayField( - models.UUIDField(verbose_name="Токен урока", unique=True, editable=False), - default=[], - verbose_name='Список скрытых уроков', - ) - teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь по умолчанию", - related_name='teacher_progress') - user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент') - course_token = models.UUIDField(verbose_name="Токен курса", editable=False) - - def __str__(self): - return '%s' % (self.user.email,) - - class Meta: - verbose_name = 'Прогресс пользователя' - verbose_name_plural = 'Прогресс пользователя' - unique_together = (("user", "course_token"),) - - -class ProgressLesson(models.Model): - progress = models.ForeignKey(to=Progress) - lesson_token = models.UUIDField(verbose_name="Токен урока", editable=False) - teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь",) - date = models.DateTimeField(verbose_name='Дата зачтения задания', blank=True, null=True) - - def __str__(self): - return self.lesson_token - - class Meta: - verbose_name = 'Прохождение уроков' - verbose_name_plural = 'Прохождение урока' - - -class UserAnswerBlock(models.Model): - progress = models.ForeignKey(to=ProgressLesson) - date = models.DateTimeField(verbose_name='Дата сдачи', auto_now_add=True) - demand_token = models.UUIDField(verbose_name="Токен правила", unique=True, editable=False) - checker = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Проверяющий",) - - class Meta: - verbose_name = 'Блок ответов пользователя' - verbose_name_plural = 'Блоки ответов пользователя' - - -class UserAnswer(models.Model): - block = models.ForeignKey(to=UserAnswerBlock) - key = models.CharField(max_length=255, blank=True, verbose_name='Наименование поля') - value = models.TextField(verbose_name='Значение в поле') - STATUS = Choices('done', 'wait', 'fail') - status = models.CharField(choices=STATUS, default=STATUS.done, max_length=20) - - class Meta: - verbose_name = 'Ответ пользователя' - verbose_name_plural = 'Ответы пользователя' diff --git a/access/models/progress.py b/access/models/progress.py index e69de29..ffc908b 100644 --- a/access/models/progress.py +++ b/access/models/progress.py @@ -0,0 +1,62 @@ +from django.conf import settings +from django.contrib.postgres.fields import ArrayField +from django.db import models +from model_utils import Choices + + +class Progress(models.Model): + hidden_lessons = ArrayField( + models.UUIDField(verbose_name="Токен урока", unique=True, editable=False), + default=[], + verbose_name='Список скрытых уроков', + ) + teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь по умолчанию", + related_name='teacher_progress') + user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент') + course_token = models.UUIDField(verbose_name="Токен курса", editable=False) + + def __str__(self): + return '%s' % (self.user.email,) + + class Meta: + verbose_name = 'Прогресс пользователя' + verbose_name_plural = 'Прогресс пользователя' + unique_together = (("user", "course_token"),) + + +class ProgressLesson(models.Model): + progress = models.ForeignKey(to=Progress) + lesson_token = models.UUIDField(verbose_name="Токен урока", editable=False) + teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь",) + date = models.DateTimeField(verbose_name='Дата зачтения задания', blank=True, null=True) + + def __str__(self): + return self.lesson_token + + class Meta: + verbose_name = 'Прохождение уроков' + verbose_name_plural = 'Прохождение урока' + + +class UserLessonAnswer(models.Model): + progress_lesson = models.ForeignKey(to=ProgressLesson) + date = models.DateTimeField(verbose_name='Дата сдачи', auto_now_add=True) + reviewer = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Проверяющий",) + + class Meta: + verbose_name = 'Блок ответов пользователя' + verbose_name_plural = 'Блоки ответов пользователя' + + +class AnswerItem(models.Model): + STATUSES = Choices('done', 'wait', 'fail') + + lesson_answer = models.ForeignKey(to=UserLessonAnswer) + question = models.TextField(verbose_name='Вопрос') # TODO подумать над хранением токена вопроса + value = models.TextField(verbose_name='Ответ') + comment = models.TextField(verbose_name='Комент', blank=True, null=True) + status = models.CharField(choices=STATUSES, default=STATUSES.wait, max_length=20) + + class Meta: + verbose_name = 'Ответ пользователя' + verbose_name_plural = 'Ответы пользователя' diff --git a/access/serializers.py b/access/serializers.py index 1d9e1cd..eef9b37 100644 --- a/access/serializers.py +++ b/access/serializers.py @@ -1,7 +1,9 @@ from django.contrib.auth import get_user_model from rest_framework import serializers -from access.models.other import Account, Progress, ProgressLesson +from access.models.other import Account +from access.models.progress import ProgressLesson +from access.models import Progress from achievements.serialers import DiplomaSerializer, AchievementsSerializer diff --git a/access/views.py b/access/views.py index 31ff8ec..450ec60 100644 --- a/access/views.py +++ b/access/views.py @@ -12,7 +12,9 @@ from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView -from access.models.other import Invite, Progress, ResetPassword, ProgressLesson +from access.models.other import Invite, ResetPassword +from access.models.progress import ProgressLesson +from access.models import Progress from access.serializers import UserSelfSerializer, UserSearchSerializer, ProgressVertexSerializer diff --git a/achievements/migrations/0001_initial.py b/achievements/migrations/0001_initial.py index 2eb504c..d706d00 100644 --- a/achievements/migrations/0001_initial.py +++ b/achievements/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-11 17:32 +# Generated by Django 1.11.6 on 2018-01-12 15:44 from __future__ import unicode_literals from django.conf import settings diff --git a/courses/admin.py b/courses/admin.py index e1016f6..6a3c5e2 100755 --- a/courses/admin.py +++ b/courses/admin.py @@ -1,9 +1,10 @@ from django.contrib import admin -from courses.models import Course, Topic, Lesson, Demand, Field +from courses.models import Course, Topic, Lesson, Requirement, Question, RightAnswer admin.site.register(Topic) admin.site.register(Lesson) admin.site.register(Course) -admin.site.register(Demand) -admin.site.register(Field) \ No newline at end of file +admin.site.register(Requirement) +admin.site.register(Question) +admin.site.register(RightAnswer) \ No newline at end of file diff --git a/courses/migrations/0001_initial.py b/courses/migrations/0001_initial.py index b516b95..11a2d02 100644 --- a/courses/migrations/0001_initial.py +++ b/courses/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-11 17:32 +# Generated by Django 1.11.6 on 2018-01-12 15:44 from __future__ import unicode_literals import django.contrib.postgres.fields @@ -38,65 +38,75 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='Demand', + name='Lesson', fields=[ ('token', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='Токен')), - ('name', models.CharField(max_length=31, unique=True, verbose_name='Название')), - ('checker', models.CharField(choices=[('student', 'student'), ('teacher', 'teacher'), ('support', 'support')], default='teacher', max_length=15, verbose_name='Проверяющий')), - ('min_balls', models.SmallIntegerField(default=50, verbose_name='Проходной бал')), + ('title', models.CharField(max_length=255, verbose_name='Название')), + ('description', models.TextField(blank=True, null=True, verbose_name='Описание')), + ('video', models.TextField(blank=True, null=True, verbose_name='Код видео')), + ('material_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=15, verbose_name='Материалы урока'), default=[], size=None)), + ('free', models.BooleanField(default=False, verbose_name='Привилегии для узла не будут проверяться')), + ('sort', models.SmallIntegerField(unique=True)), ], options={ - 'verbose_name': 'Требования', - 'verbose_name_plural': 'Требования', + 'verbose_name': 'Урок', + 'verbose_name_plural': 'Уроки', + 'ordering': ('sort',), }, ), migrations.CreateModel( - name='Field', + name='LessonRequirement', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('label', models.CharField(max_length=255, verbose_name='Надпись у поля')), + ('sort', models.SmallIntegerField(default=1)), + ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Lesson')), + ], + options={ + 'verbose_name': 'Порядок требований', + 'verbose_name_plural': 'Порядок требований', + 'ordering': ('sort',), + }, + ), + migrations.CreateModel( + name='Question', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField(verbose_name='Вопрос')), ('type', models.CharField(choices=[('text', 'text'), ('char', 'char'), ('boolean', 'boolean'), ('file', 'file')], default='char', max_length=20)), ('multiple', models.BooleanField(default=False)), ('null', models.BooleanField(default=False)), - ('answers', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=255), blank=True, null=True, size=None)), ('balls', models.SmallIntegerField(default=100, verbose_name='Вознаграждение')), - ('match', models.CharField(blank=True, max_length=255, null=True, verbose_name='Если не нулевое значение, то при точном сопоставлении даёт положителбный ответ')), - ('demand', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Demand')), ], options={ - 'verbose_name': 'Поле', - 'verbose_name_plural': 'Поля', + 'verbose_name': 'Вопрос', + 'verbose_name_plural': 'Вопросы', }, ), migrations.CreateModel( - name='Lesson', + name='Requirement', fields=[ ('token', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='Токен')), - ('title', models.CharField(max_length=255, verbose_name='Название')), - ('description', models.TextField(blank=True, null=True, verbose_name='Описание')), - ('video', models.TextField(blank=True, null=True, verbose_name='Код видео')), - ('material_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=15, verbose_name='Материалы урока'), default=[], size=None)), - ('free', models.BooleanField(default=False, verbose_name='Привилегии для узла не будут проверяться')), - ('sort', models.SmallIntegerField(unique=True)), + ('name', models.CharField(max_length=31, unique=True, verbose_name='Название')), + ('checker', models.CharField(choices=[('student', 'student'), ('teacher', 'teacher'), ('auto', 'auto')], default='teacher', max_length=15, verbose_name='Проверяющий')), + ('min_balls', models.SmallIntegerField(default=50, verbose_name='Проходной бал')), ], options={ - 'verbose_name': 'Урок', - 'verbose_name_plural': 'Уроки', - 'ordering': ('sort',), + 'verbose_name': 'Требования', + 'verbose_name_plural': 'Требования', }, ), migrations.CreateModel( - name='LessonDemand', + name='RightAnswer', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort', models.SmallIntegerField(default=1)), - ('demand', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Demand')), - ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Lesson')), + ('text', models.TextField(verbose_name='Верный ответ')), + ('success_comment', models.TextField(blank=True, null=True, verbose_name='Комментарий при верном ответе')), + ('error_comment', models.TextField(blank=True, null=True, verbose_name='Комментарий при ошибке')), + ('question', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='courses.Question')), ], options={ - 'verbose_name': 'Порядок требований', - 'verbose_name_plural': 'Порядок требований', - 'ordering': ('sort',), + 'verbose_name': 'Верный ответ', + 'verbose_name_plural': 'Верные ответы', }, ), migrations.CreateModel( @@ -114,13 +124,23 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Темы', }, ), + migrations.AddField( + model_name='question', + name='requirement', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Requirement'), + ), + migrations.AddField( + model_name='lessonrequirement', + name='requirement', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Requirement'), + ), migrations.AddField( model_name='lesson', name='topic', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Topic', verbose_name='Тема'), ), migrations.AlterUniqueTogether( - name='lessondemand', - unique_together=set([('lesson', 'demand', 'sort')]), + name='lessonrequirement', + unique_together=set([('lesson', 'requirement', 'sort')]), ), ] diff --git a/courses/migrations/0002_init_demands.py b/courses/migrations/0002_init_demands.py index 5a18779..d0623f6 100644 --- a/courses/migrations/0002_init_demands.py +++ b/courses/migrations/0002_init_demands.py @@ -1,27 +1,27 @@ from __future__ import unicode_literals -from courses.models import Demand, Field +from courses.models import Requirement, Question from django.db import migrations def init_demands(*_args, **_kwargs): - d, c = Demand.objects.get_or_create( + requirement, created = Requirement.objects.get_or_create( min_balls=51, name="Стандартные требования", ) - Field.objects.get_or_create( - demand=d, - label='Комментарий', + Question.objects.get_or_create( + requirement=requirement, + text='Комментарий', type='text', null=True, balls=50, ) - Field.objects.get_or_create( - demand=d, - label='Приложенные файлы', + Question.objects.get_or_create( + requirement=requirement, + text='Приложенные файлы', type='files', null=True, multiple=True, diff --git a/courses/migrations/0003_lesson_old_id.py b/courses/migrations/0003_lesson_old_id.py new file mode 100644 index 0000000..e2dd994 --- /dev/null +++ b/courses/migrations/0003_lesson_old_id.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-01-12 16:02 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('courses', '0002_init_demands'), + ] + + operations = [ + migrations.AddField( + model_name='lesson', + name='old_id', + field=models.IntegerField(blank=True, null=True), + ), + ] diff --git a/courses/models.py b/courses/models.py index 9947d4e..49febc8 100755 --- a/courses/models.py +++ b/courses/models.py @@ -120,6 +120,8 @@ class Lesson(models.Model): free = models.BooleanField(default=False, verbose_name='Привилегии для узла не будут проверяться') sort = models.SmallIntegerField(unique=True) + old_id = models.IntegerField(null=True, blank=True) + def __str__(self): return self.title @@ -129,20 +131,21 @@ class Lesson(models.Model): ordering = ('sort', ) -class LessonDemand(models.Model): - demand = models.ForeignKey(to='Demand') +class LessonRequirement(models.Model): lesson = models.ForeignKey(to=Lesson) + requirement = models.ForeignKey(to='courses.Requirement') sort = models.SmallIntegerField(default=1) class Meta: verbose_name = "Порядок требований" verbose_name_plural = "Порядок требований" ordering = ('sort', ) - unique_together = ('lesson', 'demand', 'sort') + unique_together = ('lesson', 'requirement', 'sort') + +class Requirement(models.Model): + CHECK_TYPES = Choices('student', 'teacher', 'auto',) -class Demand(models.Model): - CHECK_TYPES = Choices('student', 'teacher', 'support',) token = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, primary_key=True, editable=False) name = models.CharField(max_length=31, verbose_name="Название", unique=True) checker = models.CharField( @@ -157,21 +160,27 @@ class Demand(models.Model): verbose_name_plural = "Требования" -class Field(models.Model): - # TODO Нужно прикрутить предварительную валидацию +class Question(models.Model): FIELD_TYPES = Choices('text', 'char', 'boolean', 'file') - demand = models.ForeignKey(to=Demand) - label = models.CharField(max_length=255, verbose_name='Надпись у поля') + + requirement = models.ForeignKey(to=Requirement) + text = models.TextField(verbose_name="Вопрос") type = models.CharField(choices=FIELD_TYPES, default=FIELD_TYPES.char, max_length=20) multiple = models.BooleanField(default=False) null = models.BooleanField(default=False) - answers = ArrayField(models.CharField(max_length=255), blank=True, null=True) balls = models.SmallIntegerField(default=100, verbose_name='Вознаграждение') - match = models.CharField( - max_length=255, - verbose_name='Если не нулевое значение, то при точном сопоставлении даёт положителбный ответ', - blank=True, null=True) class Meta: - verbose_name = "Поле" - verbose_name_plural = "Поля" + verbose_name = "Вопрос" + verbose_name_plural = "Вопросы" + + +class RightAnswer(models.Model): + question = models.OneToOneField(to=Question) + text = models.TextField(verbose_name="Верный ответ") + success_comment = models.TextField(blank=True, null=True, verbose_name="Комментарий при верном ответе") + error_comment = models.TextField(blank=True, null=True, verbose_name="Комментарий при ошибке") + + class Meta: + verbose_name = "Верный ответ" + verbose_name_plural = "Верные ответы" diff --git a/csv/load_bills.py b/csv/load_bills.py index 398d3bc..01ffb2c 100644 --- a/csv/load_bills.py +++ b/csv/load_bills.py @@ -15,7 +15,7 @@ django.setup() from yandex_money.models import Payment from finance.models import Bill, Invoice -from access.models.other import Progress +from access.models import Progress from courses.models import Course if __name__ == '__main__': diff --git a/csv/load_comments.py b/csv/load_comments.py index 787e91b..0e65d8e 100644 --- a/csv/load_comments.py +++ b/csv/load_comments.py @@ -12,7 +12,8 @@ sys.path.append("../") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") django.setup() -from storage.models import Comment, File +from storage.models import File +from access.models.progress import UserLessonAnswer, AnswerItem, ProgressLesson if __name__ == '__main__': csv.field_size_limit(500 * 1024 * 1024) diff --git a/csv/load_courses.py b/csv/load_courses.py index 52f41cc..f6bfa92 100644 --- a/csv/load_courses.py +++ b/csv/load_courses.py @@ -10,80 +10,76 @@ django.setup() from courses.api import InApiTeacher from django.contrib.auth import get_user_model -from courses.models import Course, Lesson, Topic, Demand, LessonDemand +from courses.models import Course, Lesson, Topic, Requirement, LessonRequirement from storage.models import File if __name__ == '__main__': - Topic.objects.all().delete() + Course.objects.all().delete() - # with open('./course/course.csv') as user_csv: - # user_reader = csv.DictReader(user_csv) - # for row in user_reader: - # row = dict(row) - # teachers = row.pop('teachers', None).split("[")[1].split("]")[0].split(", ") - # course, _is_create = Course.objects.get_or_create(**row) - # - # try: - # for teacher in teachers: - # teacher = teacher.replace("\'", "") - # if teacher: - # teacher = get_user_model().objects.get(email=teacher).out_key - # InApiTeacher.add_teacher(course.slug, teacher) - # - # except get_user_model().DoesNotExist: - # print('Плохо') + with open('./course/course.csv') as user_csv: + user_reader = csv.DictReader(user_csv) + for row in user_reader: + row = dict(row) + teachers = row.pop('teachers', None).split("[")[1].split("]")[0].split(", ") + course, _is_create = Course.objects.get_or_create(**row) - with open('./course/old_new_id.csv', 'w') as write_id_csv: - writer = csv.writer(write_id_csv) - writer.writerow(['old_id', 'new_id']) - with open('./course/vertex.csv') as vertex_csv: - t_sort = 0 - l_sort = 0 - vertex_reader = csv.DictReader(vertex_csv) - for row in vertex_reader: - row = dict(row) - model_type = row.pop('type', None) - description = row.pop('description', None) - title = row.pop('title', None) - pk = row.pop('id', None) - materials = [] - try: - m = row.pop('materials', None) - if m: - materials = [File.objects.get(id=i).key for i in m.split("[")[1].split("]")[0].split(", ")] - except ValueError: - pass + try: + for teacher in teachers: + teacher = teacher.replace("\'", "") + if teacher: + teacher = get_user_model().objects.get(email=teacher).out_key + InApiTeacher.add_teacher(course.slug, teacher) - if model_type == 'topic': - t_sort += 1 - course = Course.objects.get(slug=row.pop('course', None)) - Topic.objects.create( - id=pk, - icon=row.pop('icon', None), - course=course, - description=description, - title=title, - sort=t_sort, - ) + except get_user_model().DoesNotExist: + print('Плохо') - else: - topic_id = row.pop('topic', None) - l_sort += 1 - topic = Topic.objects.get(id=topic_id) - small_vertex = Lesson.objects.create( - video=row.pop('video', None), - material_tokens=materials, - topic=topic, - free=row['free'], - description=description, - title=title, - sort=l_sort, - ) + with open('./course/vertex.csv') as vertex_csv: + t_sort = 0 + l_sort = 0 + vertex_reader = csv.DictReader(vertex_csv) + for row in vertex_reader: + row = dict(row) + model_type = row.pop('type', None) + description = row.pop('description', None) + title = row.pop('title', None) + pk = row.pop('id', None) + materials = [] + try: + m = row.pop('materials', None) + if m: + materials = [File.objects.get(id=i).key for i in m.split("[")[1].split("]")[0].split(", ")] + except ValueError: + pass - writer.writerow([pk, small_vertex.token]) + if model_type == 'topic': + t_sort += 1 + course = Course.objects.get(slug=row.pop('course', None)) + Topic.objects.create( + id=pk, + icon=row.pop('icon', None), + course=course, + description=description, + title=title, + sort=t_sort, + ) - if model_type == 'task': - LessonDemand.objects.create( - lesson=small_vertex, - demand=Demand.objects.get(name="Стандартные требования"), - ) \ No newline at end of file + else: + topic_id = row.pop('topic', None) + l_sort += 1 + topic = Topic.objects.get(id=topic_id) + small_vertex = Lesson.objects.create( + video=row.pop('video', None), + material_tokens=materials, + topic=topic, + free=row['free'], + description=description, + title=title, + sort=l_sort, + old_id=pk, + ) + + if model_type == 'task': + LessonRequirement.objects.create( + lesson=small_vertex, + requirement=Requirement.objects.get(name="Стандартные требования"), + ) \ No newline at end of file diff --git a/csv/load_perm.py b/csv/load_perm.py index 1f89621..feaad95 100644 --- a/csv/load_perm.py +++ b/csv/load_perm.py @@ -14,16 +14,11 @@ django.setup() from django.contrib.auth.models import Group from django.contrib.auth import get_user_model -from access.models.other import Progress, ProgressLesson +from access.models.progress import ProgressLesson +from access.models import Progress from courses.models import Lesson, Course -def find_id(old_id): - with open('./course/old_new_id.csv') as id_csv: - id_reader = csv.DictReader(id_csv) - r = [a['new_id'] for a in id_reader if int(a['old_id']) == old_id][0] - return r - if __name__ == '__main__': Progress.objects.all().delete() with open('./access/progress.csv') as progress_csv: @@ -53,7 +48,7 @@ if __name__ == '__main__': for pivot in pivots: pv = ProgressLesson.objects.create( progress=p, - lesson_token=find_id(pivot['id']), + lesson_token=Lesson.objects.get(old_id=pivot['id']).token, teacher=get_user_model().objects.get(email=pivot['teacher']), ) diff --git a/csv/load_users.py b/csv/load_users.py index 9930fa4..e622c9a 100644 --- a/csv/load_users.py +++ b/csv/load_users.py @@ -1,4 +1,4 @@ -import os, sys, django, csv, json +import os, sys, django, csv sys.path.append("../") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") diff --git a/finance/migrations/0001_initial.py b/finance/migrations/0001_initial.py index b24d70f..0e172e4 100644 --- a/finance/migrations/0001_initial.py +++ b/finance/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-11 17:32 +# Generated by Django 1.11.6 on 2018-01-12 15:44 from __future__ import unicode_literals from django.conf import settings @@ -21,7 +21,7 @@ class Migration(migrations.Migration): name='Bill', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('course_token', models.UUIDField(editable=False, unique=True, verbose_name='Токен курса')), + ('course_token', models.UUIDField(editable=False, verbose_name='Токен курса')), ('comment', models.TextField(blank=True, editable=False, help_text='Будет показано пользователю', verbose_name='Комментарий продавца')), ('description', models.TextField(blank=True, verbose_name='Внутренняя заметка')), ('opener', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Ответственный сотрудник')), diff --git a/finance/migrations/0002_auto_20180112_1013.py b/finance/migrations/0002_auto_20180112_1013.py deleted file mode 100644 index 9d34dc1..0000000 --- a/finance/migrations/0002_auto_20180112_1013.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-12 10:13 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('finance', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='bill', - name='course_token', - field=models.UUIDField(editable=False, verbose_name='Токен курса'), - ), - ] diff --git a/library/migrations/0001_initial.py b/library/migrations/0001_initial.py index ee8e393..651b76f 100644 --- a/library/migrations/0001_initial.py +++ b/library/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-11 17:32 +# Generated by Django 1.11.6 on 2018-01-12 15:44 from __future__ import unicode_literals import datetime diff --git a/storage/migrations/0001_initial.py b/storage/migrations/0001_initial.py index f016872..4a5a967 100644 --- a/storage/migrations/0001_initial.py +++ b/storage/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-01-11 17:32 +# Generated by Django 1.11.6 on 2018-01-12 15:44 from __future__ import unicode_literals from django.db import migrations, models