diff --git a/apps/course/admin.py b/apps/course/admin.py index 683f950f..dab42062 100644 --- a/apps/course/admin.py +++ b/apps/course/admin.py @@ -1,6 +1,7 @@ from django.contrib import admin +from mptt.admin import MPTTModelAdmin, DraggableMPTTAdmin -from .models import Course, Category, Lesson, Material +from .models import Course, Category, Lesson, Material, CourseComment, LessonComment @admin.register(Course) @@ -35,3 +36,13 @@ class MaterialAdmin(admin.ModelAdmin): list_display = ( 'title', ) + + +@admin.register(CourseComment) +class CourseCommentAdmin(DraggableMPTTAdmin): + pass + + +@admin.register(LessonComment) +class LessonCommentAdmin(DraggableMPTTAdmin): + pass diff --git a/apps/course/migrations/0012_comment.py b/apps/course/migrations/0012_comment.py new file mode 100644 index 00000000..fe3f6e14 --- /dev/null +++ b/apps/course/migrations/0012_comment.py @@ -0,0 +1,35 @@ +# Generated by Django 2.0.1 on 2018-01-29 17:09 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('course', '0011_auto_20180129_1527'), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(default='', verbose_name='Текст комментария')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('update_at', models.DateTimeField(auto_now=True)), + ('lft', models.PositiveIntegerField(db_index=True, editable=False)), + ('rght', models.PositiveIntegerField(db_index=True, editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(db_index=True, editable=False)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.Comment')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/course/migrations/0013_auto_20180129_1715.py b/apps/course/migrations/0013_auto_20180129_1715.py new file mode 100644 index 00000000..47be2f6f --- /dev/null +++ b/apps/course/migrations/0013_auto_20180129_1715.py @@ -0,0 +1,17 @@ +# Generated by Django 2.0.1 on 2018-01-29 17:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0012_comment'), + ] + + operations = [ + migrations.AlterModelOptions( + name='comment', + options={'verbose_name': 'Комментарий', 'verbose_name_plural': 'Комментарии'}, + ), + ] diff --git a/apps/course/migrations/0014_auto_20180129_1726.py b/apps/course/migrations/0014_auto_20180129_1726.py new file mode 100644 index 00000000..8330ba86 --- /dev/null +++ b/apps/course/migrations/0014_auto_20180129_1726.py @@ -0,0 +1,70 @@ +# Generated by Django 2.0.1 on 2018-01-29 17:26 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('course', '0013_auto_20180129_1715'), + ] + + operations = [ + migrations.CreateModel( + name='CourseComment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(default='', verbose_name='Текст комментария')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('update_at', models.DateTimeField(auto_now=True)), + ('lft', models.PositiveIntegerField(db_index=True, editable=False)), + ('rght', models.PositiveIntegerField(db_index=True, editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(db_index=True, editable=False)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course.Course')), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.CourseComment')), + ], + options={ + 'verbose_name': 'Комментарий', + 'verbose_name_plural': 'Комментарии', + 'abstract': False, + }, + ), + migrations.CreateModel( + name='LessonComment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(default='', verbose_name='Текст комментария')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('update_at', models.DateTimeField(auto_now=True)), + ('lft', models.PositiveIntegerField(db_index=True, editable=False)), + ('rght', models.PositiveIntegerField(db_index=True, editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(db_index=True, editable=False)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course.Lesson')), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.LessonComment')), + ], + options={ + 'verbose_name': 'Комментарий', + 'verbose_name_plural': 'Комментарии', + 'abstract': False, + }, + ), + migrations.RemoveField( + model_name='comment', + name='author', + ), + migrations.RemoveField( + model_name='comment', + name='parent', + ), + migrations.DeleteModel( + name='Comment', + ), + ] diff --git a/apps/course/migrations/0015_auto_20180129_1733.py b/apps/course/migrations/0015_auto_20180129_1733.py new file mode 100644 index 00000000..986fb1ed --- /dev/null +++ b/apps/course/migrations/0015_auto_20180129_1733.py @@ -0,0 +1,135 @@ +# Generated by Django 2.0.1 on 2018-01-29 17:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('course', '0014_auto_20180129_1726'), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(default='', verbose_name='Текст комментария')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('update_at', models.DateTimeField(auto_now=True)), + ('lft', models.PositiveIntegerField(db_index=True, editable=False)), + ('rght', models.PositiveIntegerField(db_index=True, editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(db_index=True, editable=False)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.Comment')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AlterModelOptions( + name='coursecomment', + options={'verbose_name': 'Комментарий курса', 'verbose_name_plural': 'Комментарии курсов'}, + ), + migrations.AlterModelOptions( + name='lessoncomment', + options={'verbose_name': 'Комментарий урока', 'verbose_name_plural': 'Комментарии уроков'}, + ), + migrations.RemoveField( + model_name='coursecomment', + name='author', + ), + migrations.RemoveField( + model_name='coursecomment', + name='content', + ), + migrations.RemoveField( + model_name='coursecomment', + name='created_at', + ), + migrations.RemoveField( + model_name='coursecomment', + name='id', + ), + migrations.RemoveField( + model_name='coursecomment', + name='level', + ), + migrations.RemoveField( + model_name='coursecomment', + name='lft', + ), + migrations.RemoveField( + model_name='coursecomment', + name='parent', + ), + migrations.RemoveField( + model_name='coursecomment', + name='rght', + ), + migrations.RemoveField( + model_name='coursecomment', + name='tree_id', + ), + migrations.RemoveField( + model_name='coursecomment', + name='update_at', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='author', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='content', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='created_at', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='id', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='level', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='lft', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='parent', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='rght', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='tree_id', + ), + migrations.RemoveField( + model_name='lessoncomment', + name='update_at', + ), + migrations.AddField( + model_name='coursecomment', + name='comment_ptr', + field=models.OneToOneField(auto_created=True, default=0, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='course.Comment'), + preserve_default=False, + ), + migrations.AddField( + model_name='lessoncomment', + name='comment_ptr', + field=models.OneToOneField(auto_created=True, default=0, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='course.Comment'), + preserve_default=False, + ), + ] diff --git a/apps/course/migrations/0016_auto_20180129_1756.py b/apps/course/migrations/0016_auto_20180129_1756.py new file mode 100644 index 00000000..56672ad6 --- /dev/null +++ b/apps/course/migrations/0016_auto_20180129_1756.py @@ -0,0 +1,24 @@ +# Generated by Django 2.0.1 on 2018-01-29 17:56 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0015_auto_20180129_1733'), + ] + + operations = [ + migrations.AlterField( + model_name='coursecomment', + name='course', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='course.Course'), + ), + migrations.AlterField( + model_name='lessoncomment', + name='lesson', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='course.Lesson'), + ), + ] diff --git a/apps/course/models.py b/apps/course/models.py index f8cfab87..0b851950 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -3,6 +3,8 @@ from django.db import models from django.utils import timezone from django.contrib.auth import get_user_model +from mptt.models import MPTTModel, TreeForeignKey + from .manager import CategoryQuerySet User = get_user_model() @@ -64,7 +66,7 @@ class Course(models.Model): return False def __str__(self): - return self.title + return str(self.id) + ' ' + self.title class Meta: verbose_name = 'Курс' @@ -116,3 +118,39 @@ class Material(models.Model): verbose_name = 'Материал' verbose_name_plural = 'Материалы' ordering = ('title',) + + +class Comment(MPTTModel): + parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.PROTECT) + author = models.ForeignKey(User, on_delete=models.PROTECT) + content = models.TextField('Текст комментария', default='') + + created_at = models.DateTimeField(auto_now_add=True) + update_at = models.DateTimeField(auto_now=True) + + @property + def created_at_humanize(self): + return arrow.get(self.created_at).humanize(locale='ru') + + def __str__(self): + return self.content + + class MPTTMeta: + order_insertion_by = ['created_at'] + abstract = True + + +class CourseComment(Comment): + course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='comments') + + class Meta: + verbose_name = 'Комментарий курса' + verbose_name_plural = 'Комментарии курсов' + + +class LessonComment(Comment): + lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, related_name='comments') + + class Meta: + verbose_name = 'Комментарий урока' + verbose_name_plural = 'Комментарии уроков'