зависимости

feature/fix_generate_pass
Andrey 8 years ago
parent 9ace79accd
commit 89150bb294
  1. 4
      access/admin.py
  2. 41
      access/migrations/0001_initial.py
  3. 20
      access/migrations/0003_auto_20180115_1953.py
  4. 52
      access/models/progress.py
  5. 2
      access/models/user.py
  6. 12
      access/serializers.py
  7. 4
      access/views.py
  8. 4
      achievements/migrations/0001_initial.py
  9. 6
      courses/admin.py
  10. 84
      courses/migrations/0001_initial.py
  11. 42
      courses/migrations/0002_init_demands.py
  12. 20
      courses/migrations/0003_lesson_old_id.py
  13. 123
      courses/models.py
  14. 15
      courses/serializers.py
  15. 4
      courses/views.py
  16. 47
      csv/load_comments.py
  17. 11
      csv/load_courses.py
  18. 2
      csv/load_storage.py
  19. 2
      finance/migrations/0001_initial.py
  20. 2
      library/migrations/0001_initial.py
  21. 14
      storage/api.py
  22. 7
      storage/migrations/0001_initial.py
  23. 7
      storage/models.py
  24. 20
      storage/tests.py

@ -1,6 +1,6 @@
from django.contrib import admin
from access.models.other import Invite, Account, ResetPassword
from access.models.progress import ProgressLesson, UserLessonAnswer, AnswerItem
from access.models.progress import ProgressLesson
from access.models import Progress
from access.models.user import User
@ -10,5 +10,3 @@ admin.site.register(Progress)
admin.site.register(Invite)
admin.site.register(ResetPassword)
admin.site.register(ProgressLesson)
admin.site.register(AnswerItem)
admin.site.register(UserLessonAnswer)

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-12 15:44
# Generated by Django 1.11.6 on 2018-01-15 17:54
from __future__ import unicode_literals
import access.models.user
@ -23,10 +23,11 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('out_key', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='Токен')),
('out_key', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='Токен')),
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
('first_name', models.CharField(blank=True, default='Гость', max_length=63, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=63, verbose_name='last name')),
@ -61,20 +62,6 @@ 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=[
@ -107,6 +94,8 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lesson_token', models.UUIDField(editable=False, verbose_name='Токен урока')),
('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата зачтения задания')),
('status', models.CharField(choices=[('done', 'done'), ('wait', 'wait'), ('fail', 'fail')], default='wait', max_length=20)),
('comment_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, verbose_name='Токен комента'), default=[], size=None)),
('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='Преподователь')),
],
@ -115,19 +104,6 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'Прохождение урока',
},
),
migrations.CreateModel(
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='Дата сдачи')),
('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': 'Блок ответов пользователя',
'verbose_name_plural': 'Блоки ответов пользователя',
},
),
migrations.CreateModel(
name='ResetPassword',
fields=[
@ -145,10 +121,9 @@ class Migration(migrations.Migration):
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='progresslesson',
unique_together=set([('progress', 'lesson_token')]),
),
migrations.AlterUniqueTogether(
name='progress',

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-15 19:53
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('access', '0002_init_group'),
]
operations = [
migrations.AlterField(
model_name='progresslesson',
name='date',
field=models.DateTimeField(auto_now_add=True, verbose_name='Дата зачтения задания'),
),
]

@ -28,35 +28,39 @@ 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)
date = models.DateTimeField(verbose_name='Дата зачтения задания', auto_now_add=True)
STATUSES = Choices('done', 'wait', 'fail')
status = models.CharField(choices=STATUSES, default=STATUSES.wait, max_length=20)
comment_tokens = ArrayField(models.UUIDField(verbose_name="Токен комента", editable=False), default=[])
def __str__(self):
return self.lesson_token
return self.progress.user.email
class Meta:
verbose_name = 'Прохождение уроков'
verbose_name_plural = 'Прохождение урока'
unique_together = ('progress', 'lesson_token')
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 = 'Ответы пользователя'
# 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 = 'Ответы пользователя'

@ -93,7 +93,7 @@ class CustomUserManager(BaseUserManager):
class User(AbstractBaseUser, PermissionsMixin):
out_key = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, primary_key=True, editable=False)
out_key = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, editable=False)
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(_('first name'), max_length=63, blank=True, default='Гость')
last_name = models.CharField(_('last name'), max_length=63, blank=True)

@ -7,7 +7,7 @@ from access.models import Progress
from achievements.serialers import DiplomaSerializer, AchievementsSerializer
class ProgressVertexSerializer(serializers.ModelSerializer):
class ProgressLessonSerializer(serializers.ModelSerializer):
teacher = serializers.SerializerMethodField()
class Meta:
@ -20,15 +20,15 @@ class ProgressVertexSerializer(serializers.ModelSerializer):
class ProgressSerializer(serializers.ModelSerializer):
vertexes = serializers.SerializerMethodField()
lessons = serializers.SerializerMethodField()
class Meta:
model = Progress
fields = ('route', 'vertexes', 'course')
fields = ('lessons', 'course_token')
@staticmethod
def get_vertexes(self):
return [ProgressVertexSerializer(i).data for i in self.progressvertex_set.all()]
def get_lessons(self):
return [ProgressLessonSerializer(i).data for i in self.progresslesson_set.all()]
class AccountSerializer(serializers.ModelSerializer):
@ -61,7 +61,7 @@ class UserSelfSerializer(serializers.ModelSerializer):
@staticmethod
def get_achievements(self):
return [AchievementsSerializer(i).data for i in self.achievements_set.all()]
return [AchievementsSerializer(i).data for i in self.achievement_set.all()]
@staticmethod
def get_account(self):

@ -15,7 +15,7 @@ from rest_framework.views import APIView
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
from access.serializers import UserSelfSerializer, UserSearchSerializer, ProgressLessonSerializer
class TeacherListView(APIView):
@ -260,7 +260,7 @@ class UpdateProgress(APIView):
)
pv.status = 2
pv.save()
return Response(ProgressVertexSerializer(pv).data, status=200)
return Response(ProgressLessonSerializer(pv).data, status=200)
except Progress.DoesNotExist:
return Response('Не найден прогресс по заданным параметрам', status=404)

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-12 15:44
# Generated by Django 1.11.6 on 2018-01-15 17:54
from __future__ import unicode_literals
from django.conf import settings
@ -12,8 +12,8 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('courses', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [

@ -1,10 +1,6 @@
from django.contrib import admin
from courses.models import Course, Topic, Lesson, Requirement, Question, RightAnswer
from courses.models import Course, Topic, Lesson
admin.site.register(Topic)
admin.site.register(Lesson)
admin.site.register(Course)
admin.site.register(Requirement)
admin.site.register(Question)
admin.site.register(RightAnswer)

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-12 15:44
# Generated by Django 1.11.6 on 2018-01-15 17:54
from __future__ import unicode_literals
import django.contrib.postgres.fields
@ -19,14 +19,15 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Course',
fields=[
('token', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='Токен')),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='Токен')),
('slug', models.SlugField(editable=False, max_length=127, unique=True)),
('title', models.CharField(max_length=255, unique=True, verbose_name='Заголовок')),
('description', models.TextField(blank=True, verbose_name='Описание')),
('level', models.CharField(choices=[('B', 'Базовый'), ('A', 'Продвинутый'), ('E', 'Экспертный'), ('B+A', 'Базовый + Продвинутый')], default='B', max_length=3, verbose_name='Уровень')),
('direction', models.SmallIntegerField(choices=[(3, 'Бизнес'), (2, 'Веб-дизайн'), (1, 'Разработка'), (4, 'Рисование'), (5, 'Музыка')], verbose_name='Направление')),
('public', models.BooleanField(default=False, verbose_name='Опубликовать')),
('teacher_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, primary_key=True, verbose_name='Токен препода'), default=[], size=None, verbose_name='Преподователи курса')),
('teacher_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, verbose_name='Токен препода'), default=[], size=None, verbose_name='Преподователи курса')),
('image', models.URLField(blank=True, max_length=255, verbose_name='Изображение')),
('big_image', models.URLField(blank=True, max_length=255, verbose_name='Большое изображение')),
('big_mobile_image', models.URLField(blank=True, help_text='Большая картинка для мобильной версии', max_length=255, verbose_name='Под мобилку')),
@ -40,13 +41,17 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Lesson',
fields=[
('token', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='Токен')),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='Токен')),
('key', models.UUIDField(default=uuid.uuid4, editable=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)),
('material_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, verbose_name='Токен материала'), default=[], size=None, verbose_name='Материалы курса')),
('free', models.BooleanField(default=False, verbose_name='Привилегии для узла не будут проверяться')),
('sort', models.SmallIntegerField(unique=True)),
('is_hm', models.BooleanField(default=False)),
('old_id', models.IntegerField(blank=True, null=True)),
],
options={
'verbose_name': 'Урок',
@ -54,61 +59,6 @@ class Migration(migrations.Migration):
'ordering': ('sort',),
},
),
migrations.CreateModel(
name='LessonRequirement',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('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)),
('balls', models.SmallIntegerField(default=100, verbose_name='Вознаграждение')),
],
options={
'verbose_name': 'Вопрос',
'verbose_name_plural': 'Вопросы',
},
),
migrations.CreateModel(
name='Requirement',
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'), ('auto', 'auto')], default='teacher', max_length=15, verbose_name='Проверяющий')),
('min_balls', models.SmallIntegerField(default=50, verbose_name='Проходной бал')),
],
options={
'verbose_name': 'Требования',
'verbose_name_plural': 'Требования',
},
),
migrations.CreateModel(
name='RightAnswer',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('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': 'Верные ответы',
},
),
migrations.CreateModel(
name='Topic',
fields=[
@ -124,23 +74,9 @@ 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='lessonrequirement',
unique_together=set([('lesson', 'requirement', 'sort')]),
),
]

@ -1,42 +0,0 @@
from __future__ import unicode_literals
from courses.models import Requirement, Question
from django.db import migrations
def init_demands(*_args, **_kwargs):
requirement, created = Requirement.objects.get_or_create(
min_balls=51,
name="Стандартные требования",
)
Question.objects.get_or_create(
requirement=requirement,
text='Комментарий',
type='text',
null=True,
balls=50,
)
Question.objects.get_or_create(
requirement=requirement,
text='Приложенные файлы',
type='files',
null=True,
multiple=True,
balls=50,
)
class Migration(migrations.Migration):
initial = True
dependencies = [
('courses', '0001_initial'),
]
operations = [
migrations.RunPython(init_demands)
]

@ -1,20 +0,0 @@
# -*- 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),
),
]

@ -64,7 +64,7 @@ class CourseManager(models.Manager):
class Course(models.Model):
token = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, primary_key=True, editable=False)
token = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, editable=False)
slug = models.SlugField(unique=True, editable=False, max_length=127)
title = models.CharField(verbose_name="Заголовок", max_length=255, unique=True)
description = models.TextField(verbose_name='Описание', blank=True)
@ -72,7 +72,7 @@ class Course(models.Model):
direction = models.SmallIntegerField(choices=COURSE_DIRECTION, verbose_name='Направление')
public = models.BooleanField(verbose_name='Опубликовать', default=False)
teacher_tokens = ArrayField(
models.UUIDField(verbose_name="Токен препода", primary_key=True, editable=False),
models.UUIDField(verbose_name="Токен препода", editable=False),
default=[],
verbose_name='Преподователи курса',
)
@ -88,7 +88,7 @@ class Course(models.Model):
def get_statistic(self):
return {
'topic_count': self.topic_set.all().count(),
'task_count': sum([topic.vertex_set.count() for topic in self.topic_set.all()])
'task_count': sum([topic.lesson_set.count() for topic in self.topic_set.all()])
}
objects = CourseManager()
@ -111,15 +111,22 @@ class Topic(models.Model):
class Lesson(models.Model):
token = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, primary_key=True, editable=False)
token = models.UUIDField(verbose_name="Токен", default=uuid.uuid4, editable=False)
key = models.UUIDField(
verbose_name="Внутрений ключ используется для расшивровки", default=uuid.uuid4, editable=False)
topic = models.ForeignKey(to=Topic, verbose_name='Тема')
title = models.CharField(verbose_name='Название', max_length=255)
description = models.TextField(verbose_name='Описание', blank=True, null=True)
video = models.TextField(verbose_name='Код видео', blank=True, null=True)
material_tokens = ArrayField(models.CharField(max_length=15, blank=True, verbose_name='Материалы урока'), default=[])
material_tokens = ArrayField(
models.UUIDField(verbose_name="Токен материала", editable=False),
default=[],
verbose_name='Материалы курса',
)
free = models.BooleanField(default=False, verbose_name='Привилегии для узла не будут проверяться')
sort = models.SmallIntegerField(unique=True)
is_hm = models.BooleanField(default=False) #TODO костыли
old_id = models.IntegerField(null=True, blank=True)
def __str__(self):
@ -131,56 +138,56 @@ class Lesson(models.Model):
ordering = ('sort', )
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', 'requirement', 'sort')
class Requirement(models.Model):
CHECK_TYPES = Choices('student', 'teacher', 'auto',)
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(
choices=CHECK_TYPES, default=CHECK_TYPES.teacher, max_length=15, verbose_name="Проверяющий",)
min_balls = models.SmallIntegerField(default=50, verbose_name='Проходной бал')
def __str__(self):
return self.name
class Meta:
verbose_name = "Требования"
verbose_name_plural = "Требования"
class Question(models.Model):
FIELD_TYPES = Choices('text', 'char', 'boolean', 'file')
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)
balls = models.SmallIntegerField(default=100, verbose_name='Вознаграждение')
class Meta:
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 = "Верные ответы"
# 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', 'requirement', 'sort')
#
#
# class Requirement(models.Model):
# CHECK_TYPES = Choices('student', 'teacher', 'auto',)
#
# 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(
# choices=CHECK_TYPES, default=CHECK_TYPES.teacher, max_length=15, verbose_name="Проверяющий",)
# min_balls = models.SmallIntegerField(default=50, verbose_name='Проходной бал')
#
# def __str__(self):
# return self.name
#
# class Meta:
# verbose_name = "Требования"
# verbose_name_plural = "Требования"
#
#
# class Question(models.Model):
# FIELD_TYPES = Choices('text', 'char', 'boolean', 'file')
#
# 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)
# balls = models.SmallIntegerField(default=100, verbose_name='Вознаграждение')
#
# class Meta:
# 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 = "Верные ответы"

@ -12,27 +12,22 @@ class TopicSerializer(serializers.ModelSerializer):
@staticmethod
def get_children(self):
return [MiniVertexSerializer(i).data for i in self.vertex_set.all()]
return [MiniLessonSerializer(i).data for i in self.lesson_set.all()]
class MiniVertexSerializer(serializers.ModelSerializer):
class MiniLessonSerializer(serializers.ModelSerializer):
class Meta:
model = Lesson
fields = ('title', 'free', 'token')
class VertexSerializer(MiniVertexSerializer):
valid_type = serializers.SerializerMethodField()
class LessonSerializer(MiniLessonSerializer):
class Meta:
model = Lesson
exclude = ('id', 'topic', 'free')
@staticmethod
def get_valid_type(self):
return self.get_valid_type_display()
class CourseInitSerializer(serializers.ModelSerializer):
@ -46,7 +41,7 @@ class CourseTreeSerializer(serializers.ModelSerializer):
class Meta:
model = Course
fields = ('tree', 'route', 'slug')
fields = ('tree', 'slug')
@staticmethod
def get_tree(self):
@ -60,7 +55,7 @@ class CourseDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Course
exclude = ('route', 'id')
exclude = ('id', )
@staticmethod
def get_level(self):

@ -3,7 +3,7 @@ from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from courses.serializers import CourseDetailSerializer, CourseTreeSerializer, VertexSerializer
from courses.serializers import CourseDetailSerializer, CourseTreeSerializer, LessonSerializer
class TreeView(APIView):
@ -47,7 +47,7 @@ class VertexDetail(APIView):
# return Response("permission denied", status=403)
# TODO: Доделать систему прав на курс
res = VertexSerializer(vertex).data
res = LessonSerializer(vertex).data
# progress = vertex.course.progress_set.filter(user=request.user)
# try:
# if progress.exists():

@ -6,38 +6,53 @@ import django
import os
import sys
from django.contrib.auth import get_user_model
from django.db import IntegrityError
sys.path.append("../")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from storage.models import File
from access.models.progress import UserLessonAnswer, AnswerItem, ProgressLesson
from storage.models import Comment, File
from courses.models import Lesson
from access.models.progress import ProgressLesson
if __name__ == '__main__':
csv.field_size_limit(500 * 1024 * 1024)
Comment.objects.all().delete()
with open('./management/comment.csv') as comment_csv:
comment_reader = csv.DictReader(comment_csv)
for row in comment_reader:
if row['type'] == 'task' or row['type'] == 'exam':
l = Lesson.objects.get(old_id=row['parent_id'])
try:
c = Comment.objects.create(
id=row['id'],
email=row['owner__email'],
p = ProgressLesson.objects.get(
lesson_token=l.token,
progress__user__email=row['student'],
)
files = [File.objects.get(id=file) for file in row['files'].split("[")[1].split("]")[0].split(',')
if not file == '']
comment = Comment.objects.create(
text=row['text'],
key=''.join(random.choice(string.ascii_letters) for x in range(15)),
email=row['owner__email'],
)
except IntegrityError:
c = Comment.objects.get(id=row['id'])
for file_id in row['files'].split("[")[1].split("]")[0].split(", "):
if file_id:
c.files.add(File.objects.get(id=file_id))
if row['status'] == 'Одобренно':
p.status = ProgressLesson.STATUSES.done
p.date = row['date']
elif row['status'] == 'Отклонено':
p.status = ProgressLesson.STATUSES.fail
else:
p.status = ProgressLesson.STATUSES.wait
p.save()
c.date = row['date']
c.save()
[comment.files.add(file) for file in files]
comment.date = row['date']
comment.save()
parent_id = int(row['parent_id'])
if row['type'] == 'task':
parent_id += 50
p.comment_tokens.append(comment.token)
except ProgressLesson.DoesNotExist:
pass

@ -10,7 +10,7 @@ django.setup()
from courses.api import InApiTeacher
from django.contrib.auth import get_user_model
from courses.models import Course, Lesson, Topic, Requirement, LessonRequirement
from courses.models import Course, Lesson, Topic
from storage.models import File
if __name__ == '__main__':
@ -47,7 +47,7 @@ if __name__ == '__main__':
try:
m = row.pop('materials', None)
if m:
materials = [File.objects.get(id=i).key for i in m.split("[")[1].split("]")[0].split(", ")]
materials = [File.objects.get(id=i).token for i in m.split("[")[1].split("]")[0].split(", ")]
except ValueError:
pass
@ -76,10 +76,5 @@ if __name__ == '__main__':
title=title,
sort=l_sort,
old_id=pk,
)
if model_type == 'task':
LessonRequirement.objects.create(
lesson=small_vertex,
requirement=Requirement.objects.get(name="Стандартные требования"),
is_hm=model_type == 'task',
)

@ -19,4 +19,4 @@ if __name__ == '__main__':
for row in storage_reader:
if row['original']:
key = ''.join(random.choice(string.ascii_letters) for _x in range(15))
File.objects.create(original=row['original'], id=row['id'], key=key)
File.objects.create(original=row['original'], id=row['id'])

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-12 15:44
# Generated by Django 1.11.6 on 2018-01-15 17:54
from __future__ import unicode_literals
from django.conf import settings

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-12 15:44
# Generated by Django 1.11.6 on 2018-01-15 17:54
from __future__ import unicode_literals
import datetime

@ -1,13 +1,9 @@
import random
import string
from storage.models import Comment, File
def upload_file(original=None, name=None, base64=None) -> File:
key = ''.join(random.choice(string.ascii_letters) for _x in range(15))
if original:
new_file = File.objects.create(key=key, original=original)
new_file = File.objects.create(original=original)
else:
new_file = File.objects.upload_as_base64(base64)
@ -27,11 +23,9 @@ def add_comment(text: str, email: str, files=None) -> Comment:
files = [] if files is None else files
key = ''.join(random.choice(string.ascii_letters) for _x in range(15))
comment = Comment.objects.create(
text=text,
email=email,
key=key,
)
for file in files:
@ -42,17 +36,17 @@ def add_comment(text: str, email: str, files=None) -> Comment:
def get_comment(key):
comment = Comment.objects.get(key=key)
comment = Comment.objects.get(token=key)
return comment
def update_comment(key, **kwargs):
comment = Comment.objects.get(key=key)
comment = Comment.objects.get(token=key)
comment.__dict__.update(kwargs)
comment.save()
return comment
def delete_comment(key):
comment = Comment.objects.get(key=key).delete()
comment = Comment.objects.get(token=key).delete()
return comment

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-12 15:44
# Generated by Django 1.11.6 on 2018-01-15 17:54
from __future__ import unicode_literals
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
@ -19,7 +20,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.CharField(max_length=63, verbose_name='email автора')),
('text', models.TextField(default='', verbose_name='Текст комментария')),
('key', models.SlugField(editable=False, unique=True, verbose_name='Получения комментария по ключу')),
('token', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='Ключ')),
('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата коментария')),
],
options={
@ -31,7 +32,7 @@ class Migration(migrations.Migration):
name='File',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.CharField(editable=False, max_length=15, unique=True, verbose_name='Внешний ключ')),
('token', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='Ключ')),
('original', models.FileField(max_length=255, unique=True, upload_to='files', verbose_name='Файл')),
('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Видимое имя файла')),
],

@ -2,6 +2,7 @@
import base64
import random
import string
import uuid
from django.core.files.base import ContentFile
from django.db import models
@ -20,7 +21,7 @@ class FileManager(models.Manager):
class File(models.Model):
key = models.CharField(max_length=15, verbose_name="Внешний ключ", unique=True, editable=False)
token = models.UUIDField(verbose_name="Ключ", default=uuid.uuid4, editable=False)
original = models.FileField(max_length=255, verbose_name='Файл', upload_to="files", unique=True)
name = models.CharField(max_length=255, null=True, blank=True, verbose_name='Видимое имя файла')
@ -38,11 +39,11 @@ class Comment(models.Model):
email = models.CharField(verbose_name="email автора", max_length=63)
text = models.TextField(default="", verbose_name="Текст комментария")
files = models.ManyToManyField(to=File, blank=True, verbose_name='Файлы')
key = models.SlugField(unique=True, verbose_name="Получения комментария по ключу", editable=False)
token = models.UUIDField(verbose_name="Ключ", default=uuid.uuid4, editable=False)
date = models.DateTimeField(auto_now_add=True, verbose_name="Дата коментария")
def __str__(self):
return '%s' % self.key
return '%s' % self.token
class Meta:
verbose_name = 'Коммент'

@ -17,12 +17,12 @@ class CommentTestCase(TestCase):
Comment.objects.all().delete()
def test_comment_get(self):
self.assertEqual(self.first_comment, get_comment(self.first_comment.key))
self.assertEqual(self.first_comment, get_comment(self.first_comment.token))
def test_comment_update(self):
new_text = "Новый текст для коммента"
update_comment(key=self.first_comment.key, text=new_text)
self.assertEqual(get_comment(self.first_comment.key).text, new_text)
update_comment(key=self.first_comment.token, text=new_text)
self.assertEqual(get_comment(self.first_comment.token).text, new_text)
# def test_comment_create(self):
# token = 'fskjfskj'
@ -37,9 +37,9 @@ class CommentTestCase(TestCase):
# self.assertEqual(comment2.files.all()[0].name, file_name)
def test_comment_delete(self):
delete_comment(self.first_comment.key)
delete_comment(self.first_comment.token)
try:
comment = get_comment(self.first_comment.id)
comment = get_comment(self.first_comment.token)
except Comment.DoesNotExist:
comment = None
@ -52,12 +52,12 @@ class FileTestCase(TestCase):
self.second_comment = add_comment(text="Привет, отличная работа", email="artem4000@gmail.com")
def test_comment_get(self):
self.assertEqual(self.first_comment, get_comment(self.first_comment.key))
self.assertEqual(self.first_comment, get_comment(self.first_comment.token))
def test_comment_update(self):
new_text = "Новый текст для коммента"
update_comment(key=self.first_comment.key, text=new_text)
self.assertEqual(get_comment(self.first_comment.key).text, new_text)
update_comment(key=self.first_comment.token, text=new_text)
self.assertEqual(get_comment(self.first_comment.token).text, new_text)
def test_comment_create(self):
token = 'fskjfskj'
@ -71,9 +71,9 @@ class FileTestCase(TestCase):
self.assertEqual(comment2.files.all()[0].name, file_name)
def test_comment_delete(self):
delete_comment(self.first_comment.key)
delete_comment(self.first_comment.token)
try:
comment = get_comment(self.first_comment.id)
comment = get_comment(self.first_comment.token)
except Comment.DoesNotExist:
comment = None

Loading…
Cancel
Save