diff --git a/access/migrations/0001_initial.py b/access/migrations/0001_initial.py index bb510b3..71c8c9f 100644 --- a/access/migrations/0001_initial.py +++ b/access/migrations/0001_initial.py @@ -1,11 +1,10 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals -import access.models -from django.db import migrations, models - import access.models.user +from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -54,6 +53,25 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Дополнительная информация о пользователе', }, ), + migrations.CreateModel( + name='Invite', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('hash', models.CharField(max_length=15, unique=True, verbose_name='Уникальный код')), + ('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата сгорания приглошения')), + ], + options={ + 'verbose_name': 'Приглошение в систему', + 'verbose_name_plural': 'Приглошения в систему', + }, + ), + migrations.CreateModel( + name='PivotProgressVertex', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.SmallIntegerField(choices=[(0, 'Выполненно'), (1, 'Ожидание'), (2, 'Не выполненно')], default=0)), + ], + ), migrations.CreateModel( name='Progress', fields=[ @@ -64,4 +82,16 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Прогресс пользователя', }, ), + migrations.CreateModel( + name='ResetPassword', + fields=[ + ('invite_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='access.Invite')), + ('password', models.CharField(max_length=63, verbose_name='Новый пароль, если есть')), + ], + options={ + 'verbose_name': 'Запрос на сброс пароля', + 'verbose_name_plural': 'Запросы на сброс пароля', + }, + bases=('access.invite',), + ), ] diff --git a/access/migrations/0002_auto_20171128_1518.py b/access/migrations/0002_auto_20171128_1518.py deleted file mode 100644 index f130974..0000000 --- a/access/migrations/0002_auto_20171128_1518.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 -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): - - initial = True - - dependencies = [ - ('access', '0001_initial'), - ('auth', '0008_alter_user_username_max_length'), - ('maps', '0001_initial'), - ('courses', '0002_auto_20171128_1518'), - ] - - operations = [ - migrations.AddField( - model_name='progress', - name='course', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='Курс'), - ), - migrations.AddField( - model_name='progress', - name='progress_list', - field=models.ManyToManyField(blank=True, to='courses.Vertex', verbose_name='Лист пройденных объектов'), - ), - migrations.AddField( - model_name='progress', - name='template', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='maps.CourseRoute', verbose_name='Шаблон для прохождения если не указан явно смотри функцию get_template()'), - ), - migrations.AddField( - model_name='progress', - name='user', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент'), - ), - migrations.AddField( - model_name='account', - name='owner', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='user', - name='groups', - field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'), - ), - migrations.AddField( - model_name='user', - name='user_permissions', - field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'), - ), - migrations.AlterUniqueTogether( - name='progress', - unique_together=set([('user', 'course')]), - ), - ] diff --git a/access/migrations/0003_auto_20171129_1639.py b/access/migrations/0003_auto_20171129_1639.py deleted file mode 100644 index bad722b..0000000 --- a/access/migrations/0003_auto_20171129_1639.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-29 16:39 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('access', '0002_auto_20171128_1518'), - ] - - operations = [ - migrations.AlterField( - model_name='progress', - name='course', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='Курс'), - ), - migrations.AlterField( - model_name='progress', - name='user', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент'), - ), - ] diff --git a/access/migrations/0004_auto_20171211_1418.py b/access/migrations/0004_auto_20171211_1418.py deleted file mode 100644 index 69cccc2..0000000 --- a/access/migrations/0004_auto_20171211_1418.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-11 14:18 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('access', '0003_auto_20171129_1639'), - ] - - operations = [ - migrations.CreateModel( - name='Invite', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('hash', models.CharField(max_length=15, unique=True, verbose_name='Уникальный код')), - ('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата сгорания приглошения')), - ], - options={ - 'verbose_name': 'Приглошение в систему', - 'verbose_name_plural': 'Приглошения в систему', - }, - ), - migrations.CreateModel( - name='ResetPassword', - fields=[ - ('invite_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='access.Invite')), - ('password', models.CharField(max_length=63, verbose_name='Новый пароль, если есть')), - ], - options={ - 'verbose_name': 'Запрос на сброс пароля', - 'verbose_name_plural': 'Запросы на сброс пароля', - }, - bases=('access.invite',), - ), - 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='Кому приглошение'), - ), - ] diff --git a/access/models/other.py b/access/models/other.py index 3c6ba9e..dd74eb7 100644 --- a/access/models/other.py +++ b/access/models/other.py @@ -2,11 +2,12 @@ from django.conf import settings from django.db import models from courses.models import Course, Vertex -from journals.models import Thread from lms.global_decorators import transaction_decorator from maps.models import CourseRoute from django.db.models import Q +from storage.models import Comment + class Invite(models.Model): owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, verbose_name="Кому приглошение", null=True, unique=True) @@ -48,9 +49,10 @@ class Account(models.Model): class Progress(models.Model): + teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь по умолчанию", + related_name='teacher_progress') user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент', null=True) course = models.ForeignKey(to=Course, verbose_name='Курс', null=True) - progress_list = models.ManyToManyField(to=Vertex, verbose_name='Лист пройденных объектов', blank=True) template = models.OneToOneField(to=CourseRoute, blank=True, null=True, verbose_name='Шаблон для прохождения если ' 'не указан явно смотри ' 'функцию get_template()') @@ -86,4 +88,16 @@ class Progress(models.Model): class Meta: verbose_name = 'Прогресс пользователя' verbose_name_plural = 'Прогресс пользователя' - unique_together = (("user", "course"),) \ No newline at end of file + unique_together = (("user", "course"),) + + +class PivotProgressVertex(models.Model): + VERTEX_STATUS = ( + (0, 'Выполненно'), + (1, 'Ожидание'), + (2, 'Не выполненно'), + ) + progress = models.ForeignKey(to=Progress) + vertex = models.ForeignKey(to=Vertex) + status = models.SmallIntegerField(choices=VERTEX_STATUS, default=0) + comment = models.ManyToManyField(to=Comment) \ No newline at end of file diff --git a/access/models/user.py b/access/models/user.py index 6db3d7d..43d90b4 100644 --- a/access/models/user.py +++ b/access/models/user.py @@ -9,8 +9,6 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from access.models.other import Invite, Account -from courses.models import Vertex -from journals.models import Thread from lms.global_decorators import transaction_decorator @@ -58,14 +56,7 @@ class CustomUserManager(BaseUserManager): user.save(using=self._db) - thread = Thread.objects.create( - key="""user_%s""" % user.id, - text="""Приватный тред пользователя %s""" % user.email, - is_recurse=True, - ) - Account.objects.create(owner=user) - thread.subscribers.add(user) if role_list: for group in role_list: diff --git a/access/views.py b/access/views.py index 84250cc..0cfd9fb 100644 --- a/access/views.py +++ b/access/views.py @@ -186,7 +186,7 @@ class ChangePasswordView(APIView): @staticmethod def post(request): if request.user.is_authenticated() and not request.user.check_password(request.JSON['old_password']): - return Response("Неверный пароль", status=404) + return Response("Неверный пароль", status=400) request.user.set_password(request.JSON['new_password']) request.user.save() return Response("Пароль был изменён", status=200) diff --git a/achievements/migrations/0001_initial.py b/achievements/migrations/0001_initial.py index c6f3d4f..17ec3d4 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 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals from django.db import migrations, models @@ -17,7 +17,8 @@ class Migration(migrations.Migration): name='Achievements', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('icon', models.ImageField(blank=True, null=True, upload_to='diplomas', verbose_name='Отображение достижения')), + ('img', models.ImageField(blank=True, null=True, upload_to='achives', verbose_name='Отображение достижения')), + ('text', models.CharField(default='', max_length=255, verbose_name='Текст достижения')), ], options={ 'verbose_name': 'Достижение', @@ -28,7 +29,7 @@ class Migration(migrations.Migration): name='Diploma', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('icon', models.ImageField(upload_to='diplomas', verbose_name='Иконка')), + ('img', models.ImageField(upload_to='diplomas', verbose_name='Иконка')), ], options={ 'verbose_name': 'Диплом', diff --git a/achievements/migrations/0002_auto_20171128_1518.py b/achievements/migrations/0002_auto_20171128_1518.py deleted file mode 100644 index a48f2d5..0000000 --- a/achievements/migrations/0002_auto_20171128_1518.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 -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): - - initial = True - - dependencies = [ - ('achievements', '0001_initial'), - ('courses', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.AddField( - model_name='skillj', - name='lesson', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='Урок'), - ), - migrations.AddField( - model_name='skillj', - name='skill', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='achievements.Skills', verbose_name='Навык'), - ), - migrations.AddField( - model_name='diplomagen', - name='course', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'), - ), - migrations.AddField( - model_name='diploma', - name='template', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='achievements.DiplomaGen', verbose_name='Использовать шаблон'), - ), - migrations.AddField( - model_name='diploma', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='achievements', - name='course', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course'), - ), - migrations.AddField( - model_name='achievements', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/achievements/migrations/0003_auto_20171205_1821.py b/achievements/migrations/0003_auto_20171205_1821.py deleted file mode 100644 index 1c1fe9c..0000000 --- a/achievements/migrations/0003_auto_20171205_1821.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-05 18:21 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('achievements', '0002_auto_20171128_1518'), - ] - - operations = [ - migrations.RemoveField( - model_name='achievements', - name='course', - ), - migrations.AlterField( - model_name='achievements', - name='icon', - field=models.ImageField(blank=True, null=True, upload_to='achives', verbose_name='Отображение достижения'), - ), - ] diff --git a/achievements/migrations/0004_auto_20171205_1823.py b/achievements/migrations/0004_auto_20171205_1823.py deleted file mode 100644 index 59a39a1..0000000 --- a/achievements/migrations/0004_auto_20171205_1823.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-05 18:23 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('achievements', '0003_auto_20171205_1821'), - ] - - operations = [ - migrations.RemoveField( - model_name='achievements', - name='user', - ), - migrations.AddField( - model_name='achievements', - name='user', - field=models.ManyToManyField(to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/achievements/migrations/0005_auto_20171205_1833.py b/achievements/migrations/0005_auto_20171205_1833.py deleted file mode 100644 index 9e54037..0000000 --- a/achievements/migrations/0005_auto_20171205_1833.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-05 18:33 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('achievements', '0004_auto_20171205_1823'), - ] - - operations = [ - migrations.RenameField( - model_name='achievements', - old_name='icon', - new_name='img', - ), - migrations.RenameField( - model_name='diploma', - old_name='icon', - new_name='img', - ), - ] diff --git a/achievements/migrations/0006_auto_20171205_1836.py b/achievements/migrations/0006_auto_20171205_1836.py deleted file mode 100644 index 31c2e54..0000000 --- a/achievements/migrations/0006_auto_20171205_1836.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-05 18:36 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('achievements', '0005_auto_20171205_1833'), - ] - - operations = [ - migrations.RenameField( - model_name='achievements', - old_name='user', - new_name='users', - ), - ] diff --git a/achievements/migrations/0007_achievements_text.py b/achievements/migrations/0007_achievements_text.py deleted file mode 100644 index 6a715de..0000000 --- a/achievements/migrations/0007_achievements_text.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-06 12:44 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('achievements', '0006_auto_20171205_1836'), - ] - - operations = [ - migrations.AddField( - model_name='achievements', - name='text', - field=models.CharField(default='', max_length=255, verbose_name='Текст достижения'), - ), - ] diff --git a/api_v1/urls.py b/api_v1/urls.py index a846ccd..d4775ad 100644 --- a/api_v1/urls.py +++ b/api_v1/urls.py @@ -3,7 +3,6 @@ from django.conf.urls import url, include urlpatterns = [ url(r'courses/', include('courses.urls')), url(r'users/', include('access.urls')), - url(r'journals/', include('journals.urls')), url(r'library/', include('library.urls')), url(r'finance/', include('finance.urls')), ] \ No newline at end of file diff --git a/courses/migrations/0001_initial.py b/courses/migrations/0001_initial.py index ae011b6..c7f13b4 100644 --- a/courses/migrations/0001_initial.py +++ b/courses/migrations/0001_initial.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals -from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -12,9 +11,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('storage', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('contenttypes', '0002_remove_content_type_name'), + ('storage', '0001_initial'), ] operations = [ @@ -33,7 +31,6 @@ class Migration(migrations.Migration): ('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, null=True, verbose_name='Под мобилку')), - ('mentors', models.ManyToManyField(blank=True, related_name='course_mentors', to=settings.AUTH_USER_MODEL, verbose_name='Кураторы')), ], options={ 'verbose_name': 'Курс', diff --git a/courses/migrations/0002_auto_20171128_1518.py b/courses/migrations/0002_auto_20171128_1518.py deleted file mode 100644 index 6bebe3a..0000000 --- a/courses/migrations/0002_auto_20171128_1518.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 -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): - - initial = True - - dependencies = [ - ('courses', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('maps', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='course', - name='route', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='maps.CourseRoute', verbose_name='Порядок прохождения по умолчанию'), - ), - migrations.AddField( - model_name='course', - name='teachers', - field=models.ManyToManyField(related_name='course_teachers', to=settings.AUTH_USER_MODEL, verbose_name='Преподаватели'), - ), - ] diff --git a/courses/migrations/0003_remove_course_mentors.py b/courses/migrations/0003_remove_course_mentors.py deleted file mode 100644 index 820a7a3..0000000 --- a/courses/migrations/0003_remove_course_mentors.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-05 11:23 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('courses', '0002_auto_20171128_1518'), - ] - - operations = [ - migrations.RemoveField( - model_name='course', - name='mentors', - ), - ] diff --git a/courses/serializers.py b/courses/serializers.py index 8d8ec5f..3a26a4f 100644 --- a/courses/serializers.py +++ b/courses/serializers.py @@ -1,7 +1,6 @@ from rest_framework import serializers from courses.models import Course, Vertex, Tutorial, Topic, Task -from maps.serializers import CourseRouteSerializer class TutorialSerializer(serializers.ModelSerializer): @@ -75,7 +74,7 @@ class CourseListSerializer(serializers.ModelSerializer): class Meta: model = Course - fields = ['id', 'title', 'statistic', 'public', + fields = ['id', 'title', 'statistic', 'public', 'hidden', 'level', 'direction', 'image', 'slug'] @staticmethod diff --git a/courses/views.py b/courses/views.py index db85ea3..50c42a8 100644 --- a/courses/views.py +++ b/courses/views.py @@ -6,7 +6,6 @@ from access.models import Progress from maps.serializers import CourseMapSerializer from courses.models import Course, Vertex from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer, MiniVertexSerializer -from journals.models import Thread class TreeView(APIView): @@ -84,15 +83,15 @@ class VertexDetail(APIView): res = VertexSerializer(vertex).data progress = vertex.course.progress_set.filter(user=request.user) - try: - if progress.exists(): - next_vertex = vertex.get_next(progress[0].get_template()) - if next_vertex: - res['next'] = MiniVertexSerializer(next_vertex).data - res['is_in_progress'] = vertex in progress[0].get_objects_in_progress() - else: - res['next'] = MiniVertexSerializer(vertex.get_next(vertex.course.route)).data - except Thread.DoesNotExist or Vertex.DoesNotExist: - res['next'] = MiniVertexSerializer(vertex.get_next(vertex.course.route)).data + # try: + # if progress.exists(): + # next_vertex = vertex.get_next(progress[0].get_template()) + # if next_vertex: + # res['next'] = MiniVertexSerializer(next_vertex).data + # res['is_in_progress'] = vertex in progress[0].get_objects_in_progress() + # else: + # res['next'] = MiniVertexSerializer(vertex.get_next(vertex.course.route)).data + # except Thread.DoesNotExist or Vertex.DoesNotExist: + # res['next'] = MiniVertexSerializer(vertex.get_next(vertex.course.route)).data return Response(res, status=200) if status == 200 else Response(status=204) diff --git a/finance/migrations/0001_initial.py b/finance/migrations/0001_initial.py index 7c29d42..77b80c9 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 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals from django.conf import settings @@ -12,9 +12,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('yandex_money', '0001_initial'), + ('yandex_money', '0002_auto_20171128_1150'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('courses', '0002_auto_20171128_1518'), + ('courses', '0002_auto_20171212_1607'), ] operations = [ diff --git a/journals/__init__.py b/journals/__init__.py deleted file mode 100755 index 26ee9c3..0000000 --- a/journals/__init__.py +++ /dev/null @@ -1 +0,0 @@ -default_app_config = "journals.apps.JournalsAppConfig" \ No newline at end of file diff --git a/journals/admin.py b/journals/admin.py deleted file mode 100644 index 58ebf6e..0000000 --- a/journals/admin.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.contrib import admin -from journals.models import Thread, Journal - -admin.site.register(Thread) -admin.site.register(Journal) \ No newline at end of file diff --git a/journals/apps.py b/journals/apps.py deleted file mode 100644 index 33c8094..0000000 --- a/journals/apps.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- -from django.apps import AppConfig - - -class JournalsAppConfig(AppConfig): - name = "journals" - verbose_name = "Журналы" \ No newline at end of file diff --git a/journals/default_threads.py b/journals/default_threads.py deleted file mode 100644 index d50c4fe..0000000 --- a/journals/default_threads.py +++ /dev/null @@ -1,75 +0,0 @@ -import os, sys, django - -from django.contrib.auth import get_user_model - -sys.path.append("../") -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") -django.setup() - - -from journals.models import Thread -from django.contrib.auth.models import Group -from lms.global_decorators import transaction_decorator - - -@transaction_decorator -def main_threads(): - Thread.objects.all().delete() - - admin_thread = Thread.objects.create( - key='Admin', - text='Тред для админов, сюда падают все журналируемые сообщения в системе, кроме личных переписок', - is_staff=True, - x=500, - y=75, - ) - - admin_thread.groups.add(Group.objects.get(name='admin')) - - management_thread = Thread.objects.create( - key='Project_management', - text='Тред для проджект-менеджеров, сюда падает статистика разного рода', - is_staff=True, - ) - - management_thread.groups.add(Group.objects.get(name='project_managers')) - management_thread.parent.add(admin_thread) - - support_thread = Thread.objects.create( - key='Support', - text='Тред сапортов, занимаются поддержкой клиента', - is_staff=True, - y=500, - ) - - support_thread.groups.add(Group.objects.get(name='supports')) - support_thread.parent.add(management_thread) - - lead_managers = Thread.objects.create( - key='Sale_lead', - text='Тред лидов, сейлзов', - is_staff=True, - x=700, - ) - - lead_managers.groups.add(Group.objects.get(name='lead_managers')) - lead_managers.parent.add(admin_thread) - - managers = Thread.objects.create( - key='Sale', - text='Тред сейлзов', - is_staff=True, - is_recurse=True, - x=700, - y=500, - ) - - managers.groups.add(Group.objects.get(name='managers')) - managers.parent.add(lead_managers) - - for user in get_user_model().objects.all(): - Thread.objects.get_or_create(key="""user_%s""" % user.id) - - -if __name__ == '__main__': - main_threads() diff --git a/journals/migrations/0001_initial.py b/journals/migrations/0001_initial.py deleted file mode 100644 index 8ecc534..0000000 --- a/journals/migrations/0001_initial.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 -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): - - initial = True - - dependencies = [ - ('storage', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('auth', '0008_alter_user_username_max_length'), - ('contenttypes', '0002_remove_content_type_name'), - ] - - operations = [ - migrations.CreateModel( - name='Journal', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extra_data', models.TextField(blank=True, null=True)), - ('object_id', models.PositiveIntegerField()), - ('action_type', models.CharField(choices=[('try', 'попытался сдать'), ('yes', 'одобрил'), ('no', 'отклонил'), ('favorite', 'добавил в избранное'), ('watch', 'просмотрел'), ('like', 'лайкнул'), ('dislike', 'дизлайкнул'), ('comment', 'оставил комментарий'), ('start', 'начал прохождение'), ('end', 'закончил прохождение'), ('create', 'создал'), ('update', 'обновил'), ('delete', 'удалил')], max_length=31)), - ('date', models.DateTimeField(auto_now_add=True)), - ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), - ('files', models.ManyToManyField(blank=True, to='storage.Storage')), - ], - ), - migrations.CreateModel( - name='Thread', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('key', models.CharField(editable=False, max_length=200, unique=True)), - ('text', models.TextField(default='', verbose_name='Описание треда')), - ('is_staff', models.BooleanField(default=False, verbose_name='Админская ли табличка')), - ('is_recurse', models.BooleanField(default=False, verbose_name='Поле аптимизации поиска')), - ('check_subscribe', models.BooleanField(default=True, verbose_name='Проверять ли подписки')), - ('x', models.SmallIntegerField(default=300)), - ('y', models.SmallIntegerField(default=300)), - ('groups', models.ManyToManyField(blank=True, to='auth.Group', verbose_name='Группы подписчиков')), - ('parent', models.ManyToManyField(blank=True, to='journals.Thread')), - ('subscribers', models.ManyToManyField(blank=True, 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='Инициатор действия или тот, на ком действие инициируется'), - ), - ] diff --git a/journals/migrations/__init__.py b/journals/migrations/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/journals/models.py b/journals/models.py deleted file mode 100755 index 5eb7ba0..0000000 --- a/journals/models.py +++ /dev/null @@ -1,100 +0,0 @@ -# coding=utf-8 -from __future__ import unicode_literals - -from django.conf import settings -from django.contrib.auth.models import Group -from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType -from django.db import models -from django.db import connection - -from courses.models import Course -from finance.models import Bill -from storage.models import Storage - -ACTION_CHOICES = ( - ('try', 'попытался сдать'), - ('yes', 'одобрил'), - ('no', 'отклонил'), - ('favorite', 'добавил в избранное'), - ('watch', 'просмотрел'), - ('like', 'лайкнул'), - ('dislike', 'дизлайкнул'), - ('comment', 'оставил комментарий'), - ('start', 'начал прохождение'), - ('end', 'закончил прохождение'), - ('create', 'создал'), - ('update', 'обновил'), - ('delete', 'удалил'), -) - - -class Journal(models.Model): - thread = models.ForeignKey(to='Thread', verbose_name='Тред') - user = models.ForeignKey( - to=settings.AUTH_USER_MODEL, verbose_name='Инициатор действия или тот, на ком действие инициируется' - ) - content_type = models.ForeignKey(to=ContentType) - extra_data = models.TextField(null=True, blank=True) - object_id = models.PositiveIntegerField() - content_object = GenericForeignKey('content_type', 'object_id') - action_type = models.CharField(max_length=31, choices=ACTION_CHOICES) - date = models.DateTimeField(auto_now_add=True) - files = models.ManyToManyField(to=Storage, blank=True) - - def __str__(self): - return '%d Пользователь %s %s %s' % (self.id, self.user.email, self.get_action_type_display(), self.thread.key) - - -class Thread(models.Model): - key = models.CharField(max_length=200, unique=True, editable=False) - text = models.TextField(default='', verbose_name='Описание треда') - is_staff = models.BooleanField(default=False, verbose_name='Админская ли табличка') - is_recurse = models.BooleanField(default=False, verbose_name='Поле аптимизации поиска') - subscribers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Подписчики', blank=True) - groups = models.ManyToManyField(to=Group, verbose_name='Группы подписчиков', blank=True) - check_subscribe = models.BooleanField(default=True, verbose_name='Проверять ли подписки') - parent = models.ManyToManyField(to='self', blank=True, symmetrical=False) - x = models.SmallIntegerField(default=300) - y = models.SmallIntegerField(default=300) - - def check_status(self): - # Определяет статус треда если такой есть. - # Возможно, костыль. - res = None - for i in self.journal_set.all(): - if i.action_type in ['try', 'yes', 'no']: - res = i.action_type - return res - - def check_perm(self, user): - res = user in self.subscribers.all() - for i in self.groups.all(): - res = res or (i in user.groups.all()) - return res or sum([int(i.check_perm(user)) for i in self.parent.all()]) - - def child_thread_count(self): - # cursor = connection.cursor() - # if self.is_recurse: - # cursor.execute(""" - # WITH RECURSIVE temp1 (to_thread_id, from_thread_id) AS ( - # SELECT T1.to_thread_id, T1.from_thread_id - # FROM journals_thread_parent T1 - # WHERE to_thread_id = %s - # UNION - # SELECT T2.to_thread_id, T2.from_thread_id - # FROM journals_thread_parent T2 - # INNER JOIN temp1 ON(T2.from_thread_id = temp1.to_thread_id) - # ) - # SELECT COUNT(*) FROM temp1 - # """, [self.id]) - # count = cursor.fetchone() - # return int(count[0]) - - return self.thread_set.count() - - def journals_count(self): - return self.journal_set.count() - - def __str__(self): - return self.key diff --git a/journals/serilizers.py b/journals/serilizers.py deleted file mode 100644 index 8771c20..0000000 --- a/journals/serilizers.py +++ /dev/null @@ -1,68 +0,0 @@ -from rest_framework import serializers - -from journals.models import Thread, Journal -from storage.serializers import StorageSerializer - - -class JournalSerializer(serializers.ModelSerializer): - user = serializers.SerializerMethodField() - files = serializers.SerializerMethodField() - label = serializers.SerializerMethodField() - - class Meta: - model = Journal - fields = ('label', 'date', 'user', 'files', 'action_type', 'object_id', ) - - @staticmethod - def get_user(self): - return self.user.get_full_name() - - @staticmethod - def get_label(self): - return self.extra_data if self.extra_data else """%s %s"""\ - % (self.user.get_full_name(), self.get_action_type_display()) - - @staticmethod - def get_files(self): - return [StorageSerializer(i).data for i in self.files.all()] - - -class ThreadDetailSerializer(serializers.ModelSerializer): - journals = serializers.SerializerMethodField() - children = serializers.SerializerMethodField() - - class Meta: - model = Thread - fields = ('journals', 'id', 'text', 'children', 'key',) - - @staticmethod - def get_journals(self): - return [JournalSerializer(i).data for i in self.journal_set.all()] - - @staticmethod - def get_children(self): - return [ThreadDetailSerializer(i).data for i in self.thread_set.all()] - - -class ThreadAdminSerializer(serializers.ModelSerializer): - count_children = serializers.SerializerMethodField() - count_journals = serializers.SerializerMethodField() - - class Meta: - model = Thread - exclude = ('is_staff', ) - - @staticmethod - def get_count_children(self): - return self.child_thread_count() - - @staticmethod - def get_count_journals(self): - return self.journals_count() - - -class ThreadUserSerializer(serializers.ModelSerializer): - - class Meta: - model = Thread - fields = ('id', 'text') \ No newline at end of file diff --git a/journals/urls.py b/journals/urls.py deleted file mode 100644 index 4469de0..0000000 --- a/journals/urls.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.conf.urls import url -from journals import views as views - -urlpatterns = [ - url(r'thread/$', views.ThreadAdminListView.as_view()), - url(r'pay-stat/([0-9]{1,99})/$', views.get_pay_stat), - url(r'thread/(?P[-\w]+)/$', views.ThreadDetailView.as_view()), - url(r'journal/$', views.JournalCreateView.as_view()), -] \ No newline at end of file diff --git a/journals/views.py b/journals/views.py deleted file mode 100644 index 6d66d80..0000000 --- a/journals/views.py +++ /dev/null @@ -1,131 +0,0 @@ -from django.contrib.auth import get_user_model -from django.contrib.contenttypes.models import ContentType -from rest_framework.permissions import IsAuthenticated -from rest_framework.views import APIView -from rest_framework.renderers import JSONRenderer -from rest_framework.response import Response -import csv -from django.http import HttpResponse, HttpResponseForbidden - -from access.models.other import Progress -from journals.models import Thread, Journal -from journals.serilizers import ThreadDetailSerializer, ThreadAdminSerializer, JournalSerializer -from lms.global_decorators import transaction_decorator -from lms.tools import decode_base64 -from storage.models import Storage - - -class ThreadAdminListView(APIView): - renderer_classes = (JSONRenderer,) - status_code = 200 - - def get(self, request): - return Response( - [ThreadAdminSerializer(thread).data for thread in Thread.objects.filter(is_staff=True)], - self.status_code, - ) - - -class ThreadDetailView(APIView): - renderer_classes = (JSONRenderer,) - permission_classes = () - status_code = 200 - - def post(self, request, key): - try: - thread = Thread.objects.get(key=key) - 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(ThreadAdminSerializer(thread).data, self.status_code, ) - except Thread.DoesNotExist: - return Response("Thread doesn't exist.", self.status_code, ) - - @staticmethod - def get(request, key): - try: - thread = Thread.objects.get(key=key) - if thread.check_perm(request.user): - return Response(ThreadDetailSerializer(thread).data, status=200) - return Response("permission denied", status=403) - - except Thread.DoesNotExist: - return Response("Thread not found", status=404) - - -def get_pay_stat(request, pk): - if not request.user.is_authenticated and (request.user.groups.filter(name="supports") or request.user.is_superuser): - return HttpResponseForbidden() - - date_from = request.GET.get('from', None) - date_to = request.GET.get('to', None) - - file_name = "teacher_%s" % pk - file_name = file_name + "__from_%s" % date_from if date_from else file_name - file_name = file_name + "__to_%s" % date_to if date_to else file_name - - journals = Journal.objects.filter(user_id=pk, action_type="yes") - journals = journals.filter(date__lt=date_to) if date_to else journals - journals = journals.filter(date__gte=date_from) if date_from else journals - - response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename="%s"' % file_name - - writer = csv.writer(response) - writer.writerow(['student_email', 'full_name', 'course', 'theme', 'task_id', 'date']) - - for i in journals.order_by('-date'): - student = get_user_model().objects.get(id=i.thread.key.split('user_')[1].split('__vertex')[0]) - writer.writerow([ - student.email, - student.get_full_name(), - i.content_object.course.title, - i.content_object.vertex_set.all()[0].title, - i.content_object.id, - i.date, - ]) - - return response - - -class JournalCreateView(APIView): - renderer_classes = (JSONRenderer,) - permission_classes = (IsAuthenticated,) - status_code = 200 - - @transaction_decorator - def post(self, request): - pk = request.JSON.get('thread_id', None) - try: - thread = Thread.objects.get(id=pk) - if request.user.is_authenticated and thread.check_perm(request.user): - action_type = request.JSON.get('action_type', None) - extra_data = request.JSON.get('extra_data', None) - object_id = request.JSON.get('object_id', None) - content_type__model = request.JSON.get('content_type__model', None) - content_type__app_label = request.JSON.get('content_type__app_label', None) - content_type = ContentType.objects.get(model=content_type__model, app_label=content_type__app_label) - - files = request.JSON.get('files', []) - files = [{'data': decode_base64(i['data']), 'name': i['name']} for i in files] - - journal = Journal.objects.create( - action_type=action_type, extra_data=extra_data, thread=thread, - content_type=content_type, object_id=object_id, - user=request.user - ) - - for i in files: - s = Storage.objects.create(original=decode_base64(i['data']), name=i['name']) - journal.files.add(s) - - if action_type == 'yes': - p = Progress.objects.get(course=journal.content_object.course, user=journal.thread.subscribers.all()[0]) - p.add_vertex(journal.content_object) - - return Response(JournalSerializer(journal).data, status=200) - return Response("permission denied", status=403) - except Thread.DoesNotExist: - return Response("Thread doesn't exist.", self.status_code,) diff --git a/library/migrations/0001_initial.py b/library/migrations/0001_initial.py index e027331..72ec65b 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 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals import datetime diff --git a/lms/settings.py b/lms/settings.py index b7986ed..38d5090 100644 --- a/lms/settings.py +++ b/lms/settings.py @@ -109,7 +109,6 @@ apps = ( 'courses', 'storage', 'finance', - 'journals', 'library', 'achievements', 'maps', diff --git a/maps/migrations/0001_initial.py b/maps/migrations/0001_initial.py index aaa8138..48b5f78 100644 --- a/maps/migrations/0001_initial.py +++ b/maps/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals from django.db import migrations, models @@ -19,6 +19,7 @@ class Migration(migrations.Migration): name='CourseMap', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='Линейное прохождение', max_length=255, verbose_name='Имя прохождения')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='К какому курсу привязан')), ], options={ @@ -30,7 +31,7 @@ class Migration(migrations.Migration): name='CourseRoute', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(blank=True, max_length=255, null=True, unique=True, verbose_name='Имя шаблона')), + ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Имя шаблона')), ('is_template', models.BooleanField(default=True, verbose_name='Может ли быть использован как шаблон')), ], options={ @@ -42,13 +43,13 @@ class Migration(migrations.Migration): name='PivotCourseMap', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort', models.SmallIntegerField(unique=True, verbose_name='Порядок сортировки')), + ('sort', models.SmallIntegerField(verbose_name='Порядок сортировки')), ('map_course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='maps.CourseMap', verbose_name='К какой сортеровке имеетотношение')), ('route', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='maps.CourseRoute', verbose_name='К какому узлу')), ], options={ - 'verbose_name': 'Порядок сортировки узла', - 'verbose_name_plural': 'Порядки сортировок узла', + 'verbose_name': 'Порядок сортировки маршрута', + 'verbose_name_plural': 'Порядки сортировок маршрутов', 'ordering': ('sort',), }, ), @@ -56,7 +57,7 @@ class Migration(migrations.Migration): name='PivotVertex', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort', models.SmallIntegerField(unique=True, verbose_name='Порядок сортировки')), + ('sort', models.SmallIntegerField(verbose_name='Порядок сортировки')), ('map_course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='maps.CourseMap', verbose_name='К какой сортеровке имеетотношение')), ('vertex', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Vertex', verbose_name='К какому узлу')), ], @@ -68,10 +69,10 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='pivotvertex', - unique_together=set([('map_course', 'vertex')]), + unique_together=set([('map_course', 'vertex'), ('sort', 'map_course')]), ), migrations.AlterUniqueTogether( name='pivotcoursemap', - unique_together=set([('map_course', 'route')]), + unique_together=set([('sort', 'route'), ('map_course', 'route')]), ), ] diff --git a/maps/migrations/0002_auto_20171129_1439.py b/maps/migrations/0002_auto_20171129_1439.py deleted file mode 100644 index ef28397..0000000 --- a/maps/migrations/0002_auto_20171129_1439.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-29 14:39 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('courses', '0002_auto_20171128_1518'), - ('maps', '0001_initial'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='pivotcoursemap', - unique_together=set([('map_course', 'route'), ('sort', 'route')]), - ), - migrations.AlterUniqueTogether( - name='pivotvertex', - unique_together=set([('sort', 'map_course'), ('map_course', 'vertex')]), - ), - ] diff --git a/maps/migrations/0003_auto_20171129_1441.py b/maps/migrations/0003_auto_20171129_1441.py deleted file mode 100644 index 1284451..0000000 --- a/maps/migrations/0003_auto_20171129_1441.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-29 14:41 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('maps', '0002_auto_20171129_1439'), - ] - - operations = [ - migrations.AlterField( - model_name='pivotcoursemap', - name='sort', - field=models.SmallIntegerField(verbose_name='Порядок сортировки'), - ), - migrations.AlterField( - model_name='pivotvertex', - name='sort', - field=models.SmallIntegerField(verbose_name='Порядок сортировки'), - ), - ] diff --git a/maps/migrations/0004_auto_20171129_1447.py b/maps/migrations/0004_auto_20171129_1447.py deleted file mode 100644 index 28f8175..0000000 --- a/maps/migrations/0004_auto_20171129_1447.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-11-29 14:47 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('maps', '0003_auto_20171129_1441'), - ] - - operations = [ - migrations.AlterModelOptions( - name='pivotcoursemap', - options={'ordering': ('sort',), 'verbose_name': 'Порядок сортировки маршрута', 'verbose_name_plural': 'Порядки сортировок маршрутов'}, - ), - ] diff --git a/maps/migrations/0005_coursemap_name.py b/maps/migrations/0005_coursemap_name.py deleted file mode 100644 index 34989b9..0000000 --- a/maps/migrations/0005_coursemap_name.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-01 20:12 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('maps', '0004_auto_20171129_1447'), - ] - - operations = [ - migrations.AddField( - model_name='coursemap', - name='name', - field=models.CharField(default='Линейное прохождение', max_length=255, verbose_name='Имя прохождения'), - ), - ] diff --git a/maps/migrations/0006_auto_20171206_1258.py b/maps/migrations/0006_auto_20171206_1258.py deleted file mode 100644 index 903a28f..0000000 --- a/maps/migrations/0006_auto_20171206_1258.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2017-12-06 12:58 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('maps', '0005_coursemap_name'), - ] - - operations = [ - migrations.AlterField( - model_name='courseroute', - name='name', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Имя шаблона'), - ), - ] diff --git a/storage/migrations/0001_initial.py b/storage/migrations/0001_initial.py index 79f7ee1..641d24b 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 2017-11-28 15:18 +# Generated by Django 1.11.6 on 2017-12-12 16:07 from __future__ import unicode_literals from django.db import migrations, models @@ -13,6 +13,13 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField(default='')), + ], + ), migrations.CreateModel( name='Storage', fields=[ @@ -25,4 +32,9 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Файлы', }, ), + migrations.AddField( + model_name='comment', + name='files', + field=models.ManyToManyField(blank=True, to='storage.Storage'), + ), ] diff --git a/storage/models.py b/storage/models.py index 63cbb14..6f0a01b 100755 --- a/storage/models.py +++ b/storage/models.py @@ -12,3 +12,8 @@ class Storage(models.Model): class Meta: verbose_name = 'Файл' verbose_name_plural = 'Файлы' + + +class Comment(models.Model): + text = models.TextField(default="") + files = models.ManyToManyField(to=Storage, blank=True) \ No newline at end of file