From 187906398b735b286a8b3dba09210294c99fe02c Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 19:13:15 +0300 Subject: [PATCH 01/14] Update lesson serializer --- api/v1/serializers/course.py | 201 ++++++++++++++++++++++++++++++----- 1 file changed, 173 insertions(+), 28 deletions(-) diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index ba6d73c7..ad6b9276 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -179,19 +179,20 @@ class CourseCreateSerializer(serializers.ModelSerializer): course=course, url=c['data']['url'], ) - for material in materials: - if 'id' in material and material['id']: - m = Material.objects.get(id=material['id']) - m.title = material['title'] - m.cover = ImageObject.objects.get(id=material['cover']) - m.short_description = material['short_description'] - m.save() - else: - m = Material.objects.create( - title=material['title'], - cover=ImageObject.objects.get(id=material['cover']), - short_description=material['short_description'], - ) + for material in materials: + if 'id' in material and material['id']: + m = Material.objects.get(id=material['id']) + m.title = material['title'] + m.cover = ImageObject.objects.get(id=material['cover']) + m.short_description = material['short_description'] + m.save() + else: + m = Material.objects.create( + title=material['title'], + cover=ImageObject.objects.get(id=material['cover']), + short_description=material['short_description'], + ) + course.materials.add(m) return course def update(self, instance, validated_data): @@ -263,20 +264,20 @@ class CourseCreateSerializer(serializers.ModelSerializer): course=course, url=c['data']['url'], ) - for material in materials: - if 'id' in material and material['id']: - m = Material.objects.get(id=material['id']) - m.title = material['title'] - m.cover = ImageObject.objects.get(id=material['cover']) - m.short_description = material['short_description'] - m.save() - else: - m = Material.objects.create( - title=material['title'], - cover=ImageObject.objects.get(id=material['cover']), - short_description=material['short_description'], - ) - course.materials.add(m) + for material in materials: + if 'id' in material and material['id']: + m = Material.objects.get(id=material['id']) + m.title = material['title'] + m.cover = ImageObject.objects.get(id=material['cover']) + m.short_description = material['short_description'] + m.save() + else: + m = Material.objects.create( + title=material['title'], + cover=ImageObject.objects.get(id=material['cover']), + short_description=material['short_description'], + ) + course.materials.add(m) return course @@ -289,6 +290,10 @@ class CourseSerializer(CourseCreateSerializer): class LessonCreateSerializer(serializers.ModelSerializer): + content = serializers.ListSerializer( + child=ContentCreateSerializer(), + required=False, + ) class Meta: model = Lesson @@ -305,12 +310,152 @@ class LessonCreateSerializer(serializers.ModelSerializer): read_only_fields = ( 'id', - 'content', 'created_at', 'update_at', ) + def create(self, validated_data): + content = validated_data.pop('content', []) + + lesson = super().create(validated_data) + + for c in content: + if c['type'] == 'text': + if 'id' in c['data'] and c['data']['id']: + t = Text.objects.get(id=c['data']['id']) + t.position = c['data']['position'] + t.title = c['data']['title'] + t.lesson = lesson + t.txt = c['data']['txt'] + t.save() + else: + t = Text.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + txt=c['data']['txt'], + ) + elif c['type'] == 'image': + if 'id' in c['data'] and c['data']['id']: + i = Image.objects.get(id=c['data']['id']) + i.position = c['data']['position'] + i.title = c['data']['title'] + i.lesson = lesson + i.img = ImageObject.objects.get(id=c['data']['img']) + i.save() + else: + i = Image.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + img=ImageObject.objects.get(id=c['data']['img']), + ) + elif c['type'] == 'image-text': + if 'id' in c['data'] and c['data']['id']: + it = ImageText.objects.get(id=c['data']['id']) + it.position = c['data']['position'] + it.title = c['data']['title'] + it.lesson = lesson + it.img = ImageObject.objects.get(id=c['data']['img']) + it.txt = c['data']['txt'] + it.save() + else: + it = ImageText.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + img=ImageObject.objects.get(id=c['data']['img']), + txt=c['data']['txt'], + ) + elif c['type'] == 'video': + if 'id' in c['data'] and c['data']['id']: + v = Video.objects.get(id=c['data']['id']) + v.position = c['data']['position'] + v.title = c['data']['title'] + v.lesson = lesson + v.url = c['data']['url'] + v.save() + else: + v = Video.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + url=c['data']['url'], + ) + return lesson + + def update(self, instance, validated_data): + content = validated_data.pop('content', []) + + lesson = super().update(instance, validated_data) + + for c in content: + if c['type'] == 'text': + if 'id' in c['data'] and c['data']['id']: + t = Text.objects.get(id=c['data']['id']) + t.position = c['data']['position'] + t.title = c['data']['title'] + t.lesson = lesson + t.txt = c['data']['txt'] + t.save() + else: + t = Text.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + txt=c['data']['txt'], + ) + elif c['type'] == 'image': + if 'id' in c['data'] and c['data']['id']: + i = Image.objects.get(id=c['data']['id']) + i.position = c['data']['position'] + i.title = c['data']['title'] + i.lesson = lesson + i.img = ImageObject.objects.get(id=c['data']['img']) + i.save() + else: + i = Image.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + img=ImageObject.objects.get(id=c['data']['img']), + ) + elif c['type'] == 'image-text': + if 'id' in c['data'] and c['data']['id']: + it = ImageText.objects.get(id=c['data']['id']) + it.position = c['data']['position'] + it.title = c['data']['title'] + it.lesson = lesson + it.img = ImageObject.objects.get(id=c['data']['img']) + it.txt = c['data']['txt'] + it.save() + else: + it = ImageText.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + img=ImageObject.objects.get(id=c['data']['img']), + txt=c['data']['txt'], + ) + elif c['type'] == 'video': + if 'id' in c['data'] and c['data']['id']: + v = Video.objects.get(id=c['data']['id']) + v.position = c['data']['position'] + v.title = c['data']['title'] + v.lesson = lesson + v.url = c['data']['url'] + v.save() + else: + v = Video.objects.create( + position=c['data']['position'], + title=c['data']['title'], + lesson=lesson, + url=c['data']['url'], + ) + return lesson + class LessonSerializer(LessonCreateSerializer): course = CourseSerializer() cover = ImageObjectSerializer() + content = ContentSerializer() From b1eac3b9e38586edbc3f3a232ae20365e667e90f Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 21:06:47 +0300 Subject: [PATCH 02/14] Minimize code --- api/v1/serializers/course.py | 172 ++++------------------------------- 1 file changed, 16 insertions(+), 156 deletions(-) diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index ad6b9276..19bace7d 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -110,12 +110,7 @@ class CourseCreateSerializer(serializers.ModelSerializer): 'update_at', ) - def create(self, validated_data): - materials = validated_data.pop('materials', []) - content = validated_data.pop('content', []) - - course = super().create(validated_data) - + def dispatch_content(self, course, validated_data, content, materials): for c in content: if c['type'] == 'text': if 'id' in c['data'] and c['data']['id']: @@ -193,91 +188,19 @@ class CourseCreateSerializer(serializers.ModelSerializer): short_description=material['short_description'], ) course.materials.add(m) + + def create(self, validated_data): + content = validated_data.pop('content', []) + materials = validated_data.pop('materials', []) + course = super().create(validated_data) + self.dispatch_content(course, validated_data, content, materials) return course def update(self, instance, validated_data): - materials = validated_data.pop('materials', []) content = validated_data.pop('content', []) - + materials = validated_data.pop('materials', []) course = super().update(instance, validated_data) - - for c in content: - if c['type'] == 'text': - if 'id' in c['data'] and c['data']['id']: - t = Text.objects.get(id=c['data']['id']) - t.position = c['data']['position'] - t.title = c['data']['title'] - t.course = course - t.txt = c['data']['txt'] - t.save() - else: - t = Text.objects.create( - position=c['data']['position'], - title=c['data']['title'], - course=course, - txt=c['data']['txt'], - ) - elif c['type'] == 'image': - if 'id' in c['data'] and c['data']['id']: - i = Image.objects.get(id=c['data']['id']) - i.position = c['data']['position'] - i.title = c['data']['title'] - i.course = course - i.img = ImageObject.objects.get(id=c['data']['img']) - i.save() - else: - i = Image.objects.create( - position=c['data']['position'], - title=c['data']['title'], - course=course, - img=ImageObject.objects.get(id=c['data']['img']), - ) - elif c['type'] == 'image-text': - if 'id' in c['data'] and c['data']['id']: - it = ImageText.objects.get(id=c['data']['id']) - it.position = c['data']['position'] - it.title = c['data']['title'] - it.course = course - it.img = ImageObject.objects.get(id=c['data']['img']) - it.txt = c['data']['txt'] - it.save() - else: - it = ImageText.objects.create( - position=c['data']['position'], - title=c['data']['title'], - course=course, - img=ImageObject.objects.get(id=c['data']['img']), - txt=c['data']['txt'], - ) - elif c['type'] == 'video': - if 'id' in c['data'] and c['data']['id']: - v = Video.objects.get(id=c['data']['id']) - v.position = c['data']['position'] - v.title = c['data']['title'] - v.course = course - v.url = c['data']['url'] - v.save() - else: - v = Video.objects.create( - position=c['data']['position'], - title=c['data']['title'], - course=course, - url=c['data']['url'], - ) - for material in materials: - if 'id' in material and material['id']: - m = Material.objects.get(id=material['id']) - m.title = material['title'] - m.cover = ImageObject.objects.get(id=material['cover']) - m.short_description = material['short_description'] - m.save() - else: - m = Material.objects.create( - title=material['title'], - cover=ImageObject.objects.get(id=material['cover']), - short_description=material['short_description'], - ) - course.materials.add(m) + self.dispatch_content(course, validated_data, content, materials) return course @@ -314,11 +237,7 @@ class LessonCreateSerializer(serializers.ModelSerializer): 'update_at', ) - def create(self, validated_data): - content = validated_data.pop('content', []) - - lesson = super().create(validated_data) - + def dispatch_content(self, lesson, validated_data, content): for c in content: if c['type'] == 'text': if 'id' in c['data'] and c['data']['id']: @@ -382,76 +301,17 @@ class LessonCreateSerializer(serializers.ModelSerializer): lesson=lesson, url=c['data']['url'], ) + + def create(self, validated_data): + content = validated_data.pop('content', []) + lesson = super().create(validated_data) + self.dispatch_content(lesson, validated_data, content) return lesson def update(self, instance, validated_data): content = validated_data.pop('content', []) - lesson = super().update(instance, validated_data) - - for c in content: - if c['type'] == 'text': - if 'id' in c['data'] and c['data']['id']: - t = Text.objects.get(id=c['data']['id']) - t.position = c['data']['position'] - t.title = c['data']['title'] - t.lesson = lesson - t.txt = c['data']['txt'] - t.save() - else: - t = Text.objects.create( - position=c['data']['position'], - title=c['data']['title'], - lesson=lesson, - txt=c['data']['txt'], - ) - elif c['type'] == 'image': - if 'id' in c['data'] and c['data']['id']: - i = Image.objects.get(id=c['data']['id']) - i.position = c['data']['position'] - i.title = c['data']['title'] - i.lesson = lesson - i.img = ImageObject.objects.get(id=c['data']['img']) - i.save() - else: - i = Image.objects.create( - position=c['data']['position'], - title=c['data']['title'], - lesson=lesson, - img=ImageObject.objects.get(id=c['data']['img']), - ) - elif c['type'] == 'image-text': - if 'id' in c['data'] and c['data']['id']: - it = ImageText.objects.get(id=c['data']['id']) - it.position = c['data']['position'] - it.title = c['data']['title'] - it.lesson = lesson - it.img = ImageObject.objects.get(id=c['data']['img']) - it.txt = c['data']['txt'] - it.save() - else: - it = ImageText.objects.create( - position=c['data']['position'], - title=c['data']['title'], - lesson=lesson, - img=ImageObject.objects.get(id=c['data']['img']), - txt=c['data']['txt'], - ) - elif c['type'] == 'video': - if 'id' in c['data'] and c['data']['id']: - v = Video.objects.get(id=c['data']['id']) - v.position = c['data']['position'] - v.title = c['data']['title'] - v.lesson = lesson - v.url = c['data']['url'] - v.save() - else: - v = Video.objects.create( - position=c['data']['position'], - title=c['data']['title'], - lesson=lesson, - url=c['data']['url'], - ) + self.dispatch_content(lesson, validated_data, content) return lesson From 24c31b314a3a0c02dc109d78bf3650fff737220e Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 22:11:04 +0300 Subject: [PATCH 03/14] Fix gallery model --- .../migrations/0012_auto_20180209_1847.py | 19 +++++++++++++++++++ apps/content/models.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 apps/content/migrations/0012_auto_20180209_1847.py diff --git a/apps/content/migrations/0012_auto_20180209_1847.py b/apps/content/migrations/0012_auto_20180209_1847.py new file mode 100644 index 00000000..d99887a1 --- /dev/null +++ b/apps/content/migrations/0012_auto_20180209_1847.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0.2 on 2018-02-09 18:47 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0011_auto_20180209_1549'), + ] + + operations = [ + migrations.AlterField( + model_name='galleryimage', + name='gallery', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gallery_images', to='content.Gallery', verbose_name='Галерея'), + ), + ] diff --git a/apps/content/models.py b/apps/content/models.py index 906ee3f9..1ee70dab 100644 --- a/apps/content/models.py +++ b/apps/content/models.py @@ -81,7 +81,7 @@ class Gallery(models.Model): class GalleryImage(models.Model): gallery = models.ForeignKey( Gallery, on_delete=models.CASCADE, - verbose_name='Галерея' + verbose_name='Галерея', related_name='gallery_images' ) img = models.ForeignKey( ImageObject, related_name='gallery_images', From 181ba1c9b78d71e4c320746877dc48da5bf1ba4a Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 22:12:09 +0300 Subject: [PATCH 04/14] Update Course and gallery serializers --- api/v1/serializers/content.py | 24 ++++++++++++----------- api/v1/serializers/course.py | 36 ++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/api/v1/serializers/content.py b/api/v1/serializers/content.py index cdaa5351..67fffd22 100644 --- a/api/v1/serializers/content.py +++ b/api/v1/serializers/content.py @@ -180,13 +180,14 @@ class ContentSerializer(serializers.ModelSerializer): return super(ContentSerializer, self).to_representation(obj) -class GallerySerializer(serializers.ModelSerializer): +class GalleryImageCreateSerializer(serializers.ModelSerializer): class Meta: - model = Gallery + model = GalleryImage fields = ( 'id', - 'title', + 'gallery', + 'img', 'created_at', 'update_at', ) @@ -198,14 +199,19 @@ class GallerySerializer(serializers.ModelSerializer): ) -class GalleryImageCreateSerializer(serializers.ModelSerializer): +class GalleryImageSerializer(GalleryImageCreateSerializer): + img = ImageObjectSerializer() + + +class GallerySerializer(serializers.ModelSerializer): + gallery_images = GalleryImageSerializer(many=True) class Meta: - model = GalleryImage + model = Gallery fields = ( 'id', - 'gallery', - 'img', + 'title', + 'gallery_images', 'created_at', 'update_at', ) @@ -215,7 +221,3 @@ class GalleryImageCreateSerializer(serializers.ModelSerializer): 'created_at', 'update_at', ) - - -class GalleryImageSerializer(GalleryImageCreateSerializer): - img = ImageObjectSerializer() diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index 19bace7d..55c82b03 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -76,6 +76,7 @@ class CourseCreateSerializer(serializers.ModelSerializer): required=False, ) materials = MaterialSerializer(many=True, required=False) + gallery = GallerySerializer() class Meta: model = Course @@ -110,7 +111,7 @@ class CourseCreateSerializer(serializers.ModelSerializer): 'update_at', ) - def dispatch_content(self, course, validated_data, content, materials): + def dispatch_content(self, course, content, materials): for c in content: if c['type'] == 'text': if 'id' in c['data'] and c['data']['id']: @@ -189,18 +190,47 @@ class CourseCreateSerializer(serializers.ModelSerializer): ) course.materials.add(m) + def dispatch_gallery(self, course, gallery): + if gallery: + if 'id' in gallery and gallery['id']: + g = Gallery.objects.get(id=gallery['id']) + g.title = gallery.get('title', g.title) + g.save() + else: + g = Gallery.objects.create( + title=gallery.get('title', '') + ) + if 'images' in gallery: + for i in gallery['images']: + if 'id' in i and i['id']: + gi = GalleryImage.objects.get(id=i['id']) + gi.gallery = g + gi.img = i['img'] + gi.save() + else: + gi = GalleryImage.objects.create( + gallery=g, + img=i['img'], + ) + course.gallery = g + course.save() + def create(self, validated_data): content = validated_data.pop('content', []) materials = validated_data.pop('materials', []) + gallery = validated_data.pop('gallery', {}) course = super().create(validated_data) - self.dispatch_content(course, validated_data, content, materials) + self.dispatch_content(course, content, materials) + self.dispatch_gallery(course, gallery) return course def update(self, instance, validated_data): content = validated_data.pop('content', []) materials = validated_data.pop('materials', []) + gallery = validated_data.pop('gallery', {}) course = super().update(instance, validated_data) - self.dispatch_content(course, validated_data, content, materials) + self.dispatch_content(course, content, materials) + self.dispatch_gallery(course, gallery) return course From d19033ea0809230e143e86dcba28332d72f7e0bf Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 22:45:45 +0300 Subject: [PATCH 05/14] Add gallery to select_related --- api/v1/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v1/views.py b/api/v1/views.py index ea96b54e..043c0fb8 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -73,7 +73,7 @@ class CategoryViewSet(ExtendedModelViewSet): class CourseViewSet(ExtendedModelViewSet): queryset = Course.objects.select_related( - 'author', 'category', 'cover', + 'author', 'category', 'cover', 'gallery', ).prefetch_related( 'likes', 'materials', 'content', ).all() From 565dc3a3f02596ad179dfd90b736918bc9795764 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 22:46:05 +0300 Subject: [PATCH 06/14] Fix formating --- apps/course/models.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/course/models.py b/apps/course/models.py index efca4682..96f81457 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -42,9 +42,11 @@ class Course(models.Model): User, on_delete=models.SET_NULL, null=True, blank=True) title = models.CharField('Название курса', max_length=100, db_index=True) short_description = models.TextField( - 'Краткое описание курса', db_index=True) + 'Краткое описание курса', db_index=True + ) from_author = models.TextField( - 'От автора', default='', null=True, blank=True) + 'От автора', default='', null=True, blank=True + ) cover = models.ForeignKey( ImageObject, related_name='course_covers', verbose_name='Обложка курса', on_delete=models.CASCADE, @@ -63,7 +65,8 @@ class Course(models.Model): duration = models.IntegerField('Продолжительность курса', default=0) is_featured = models.BooleanField(default=False) status = models.PositiveSmallIntegerField( - 'Статус', default=0, choices=STATUS_CHOICES) + 'Статус', default=0, choices=STATUS_CHOICES + ) likes = models.ManyToManyField(Like, blank=True) materials = models.ManyToManyField('Material', blank=True) gallery = models.ForeignKey( @@ -141,7 +144,8 @@ class Lesson(models.Model): title = models.CharField('Название урока', max_length=100) short_description = models.TextField('Краткое описание урока') course = models.ForeignKey( - Course, on_delete=models.CASCADE, related_name='lessons') + Course, on_delete=models.CASCADE, related_name='lessons' + ) cover = models.ForeignKey( ImageObject, related_name='lesson_covers', verbose_name='Обложка урока', on_delete=models.CASCADE, @@ -207,7 +211,8 @@ class Comment(PolymorphicMPTTModel): class CourseComment(Comment): course = models.ForeignKey( - Course, on_delete=models.CASCADE, related_name='comments') + Course, on_delete=models.CASCADE, related_name='comments' + ) class Meta(Comment.Meta): verbose_name = 'Комментарий курса' @@ -216,7 +221,8 @@ class CourseComment(Comment): class LessonComment(Comment): lesson = models.ForeignKey( - Lesson, on_delete=models.CASCADE, related_name='comments') + Lesson, on_delete=models.CASCADE, related_name='comments' + ) class Meta(Comment.Meta): verbose_name = 'Комментарий урока' From 104f84ec8d2fa4a74e5f1182ca6bd52e54a4f552 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Fri, 9 Feb 2018 22:46:28 +0300 Subject: [PATCH 07/14] Fix settings --- project/settings.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/project/settings.py b/project/settings.py index a450d5b2..10c5e93b 100644 --- a/project/settings.py +++ b/project/settings.py @@ -186,13 +186,16 @@ ACTIVE_LINK_STRICT = True # DRF settings REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.SessionAuthentication', - ], - 'DEFAULT_PERMISSION_CLASSES': [ + ), + 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.AllowAny', - ], + ), + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework.renderers.JSONRenderer', + ), 'DEFAULT_FILTER_BACKENDS': ( 'django_filters.rest_framework.DjangoFilterBackend', 'rest_framework.filters.SearchFilter', From b4de8828bf153b99a241820de5e4502e2211dcfb Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:03:39 +0300 Subject: [PATCH 08/14] Fix gallery modela --- .../migrations/0013_auto_20180212_0537.py | 40 +++++++++++++++++++ apps/content/models.py | 12 +----- 2 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 apps/content/migrations/0013_auto_20180212_0537.py diff --git a/apps/content/migrations/0013_auto_20180212_0537.py b/apps/content/migrations/0013_auto_20180212_0537.py new file mode 100644 index 00000000..bb595917 --- /dev/null +++ b/apps/content/migrations/0013_auto_20180212_0537.py @@ -0,0 +1,40 @@ +# Generated by Django 2.0.2 on 2018-02-12 05:37 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0012_auto_20180209_1847'), + ] + + operations = [ + migrations.AlterModelOptions( + name='gallery', + options={'base_manager_name': 'objects'}, + ), + migrations.RemoveField( + model_name='gallery', + name='created_at', + ), + migrations.RemoveField( + model_name='gallery', + name='id', + ), + migrations.RemoveField( + model_name='gallery', + name='title', + ), + migrations.RemoveField( + model_name='gallery', + name='update_at', + ), + migrations.AddField( + model_name='gallery', + name='content_ptr', + field=models.OneToOneField(auto_created=True, default=1, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='content.Content'), + preserve_default=False, + ), + ] diff --git a/apps/content/models.py b/apps/content/models.py index 1ee70dab..6f0932bc 100644 --- a/apps/content/models.py +++ b/apps/content/models.py @@ -66,16 +66,8 @@ class Video(Content): url = models.URLField('Ссылка') -class Gallery(models.Model): - title = models.CharField('Заголовок', max_length=100, default='') - - created_at = models.DateTimeField(auto_now_add=True) - update_at = models.DateTimeField(auto_now=True) - - class Meta: - verbose_name = 'Галерея' - verbose_name_plural = 'Галереи' - ordering = ('-created_at',) +class Gallery(Content): + pass class GalleryImage(models.Model): From 976fe9191d5bb7cb5b775d9731e6866d403782d0 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:04:37 +0300 Subject: [PATCH 09/14] Fix gallery field of Course model --- .../migrations/0030_auto_20180212_0537.py | 19 +++++++++++++++++++ apps/course/models.py | 1 + 2 files changed, 20 insertions(+) create mode 100644 apps/course/migrations/0030_auto_20180212_0537.py diff --git a/apps/course/migrations/0030_auto_20180212_0537.py b/apps/course/migrations/0030_auto_20180212_0537.py new file mode 100644 index 00000000..c96cca33 --- /dev/null +++ b/apps/course/migrations/0030_auto_20180212_0537.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0.2 on 2018-02-12 05:37 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0029_auto_20180209_0911'), + ] + + operations = [ + migrations.AlterField( + model_name='course', + name='gallery', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='results_gallery', to='content.Gallery', verbose_name='Галерея работ'), + ), + ] diff --git a/apps/course/models.py b/apps/course/models.py index 96f81457..0eb620cb 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -72,6 +72,7 @@ class Course(models.Model): gallery = models.ForeignKey( Gallery, verbose_name='Галерея работ', on_delete=models.CASCADE, null=True, blank=True, + related_name='results_gallery', ) created_at = models.DateTimeField(auto_now_add=True) From 4b913d2f1cfadc9d9486f056cc46c9b13e87ddc4 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:05:12 +0300 Subject: [PATCH 10/14] Add gallery handler for create with course --- api/v1/serializers/content.py | 60 ++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/api/v1/serializers/content.py b/api/v1/serializers/content.py index 67fffd22..e1159b2e 100644 --- a/api/v1/serializers/content.py +++ b/api/v1/serializers/content.py @@ -13,6 +13,7 @@ class ContentCreateSerializer(serializers.Serializer): 'text', 'image', 'image-text', + 'images', 'video', ) type = serializers.ChoiceField(choices=TYPE_CHOICES) @@ -27,6 +28,8 @@ class ContentCreateSerializer(serializers.Serializer): return ImageTextSerializer(obj, context=self.context).to_representation(obj) elif isinstance(obj, Video): return VideoSerializer(obj, context=self.context).to_representation(obj) + elif isinstance(obj, Gallery): + return GallerySerializer(obj, context=self.context).to_representation(obj) return super(ContentSerializer, self).to_representation(obj) @@ -154,32 +157,6 @@ class VideoSerializer(VideoCreateSerializer): pass -class ContentSerializer(serializers.ModelSerializer): - - class Meta: - model = Content - fields = ( - 'id', - 'course', - 'lesson', - 'title', - 'position', - 'created_at', - 'update_at', - ) - - def to_representation(self, obj): - if isinstance(obj, Image): - return ImageSerializer(obj, context=self.context).to_representation(obj) - elif isinstance(obj, Text): - return TextSerializer(obj, context=self.context).to_representation(obj) - elif isinstance(obj, ImageText): - return ImageTextSerializer(obj, context=self.context).to_representation(obj) - elif isinstance(obj, Video): - return VideoSerializer(obj, context=self.context).to_representation(obj) - return super(ContentSerializer, self).to_representation(obj) - - class GalleryImageCreateSerializer(serializers.ModelSerializer): class Meta: @@ -210,7 +187,10 @@ class GallerySerializer(serializers.ModelSerializer): model = Gallery fields = ( 'id', + 'course', + 'lesson', 'title', + 'position', 'gallery_images', 'created_at', 'update_at', @@ -221,3 +201,31 @@ class GallerySerializer(serializers.ModelSerializer): 'created_at', 'update_at', ) + + +class ContentSerializer(serializers.ModelSerializer): + + class Meta: + model = Content + fields = ( + 'id', + 'course', + 'lesson', + 'title', + 'position', + 'created_at', + 'update_at', + ) + + def to_representation(self, obj): + if isinstance(obj, Image): + return ImageSerializer(obj, context=self.context).to_representation(obj) + elif isinstance(obj, Text): + return TextSerializer(obj, context=self.context).to_representation(obj) + elif isinstance(obj, ImageText): + return ImageTextSerializer(obj, context=self.context).to_representation(obj) + elif isinstance(obj, Video): + return VideoSerializer(obj, context=self.context).to_representation(obj) + elif isinstance(obj, Gallery): + return GallerySerializer(obj, context=self.context).to_representation(obj) + return super(ContentSerializer, self).to_representation(obj) From 9d6cf16bccf85114145585806166b956e8cbfdd6 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:05:41 +0300 Subject: [PATCH 11/14] Add gallery handler for create with course --- api/v1/serializers/course.py | 91 ++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 20 deletions(-) diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index 55c82b03..3f78a71f 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -130,14 +130,14 @@ class CourseCreateSerializer(serializers.ModelSerializer): ) elif c['type'] == 'image': if 'id' in c['data'] and c['data']['id']: - i = Image.objects.get(id=c['data']['id']) - i.position = c['data']['position'] - i.title = c['data']['title'] - i.course = course - i.img = ImageObject.objects.get(id=c['data']['img']) - i.save() + image = Image.objects.get(id=c['data']['id']) + image.position = c['data']['position'] + image.title = c['data']['title'] + image.course = course + image.img = ImageObject.objects.get(id=c['data']['img']) + image.save() else: - i = Image.objects.create( + image = Image.objects.create( position=c['data']['position'], title=c['data']['title'], course=course, @@ -175,6 +175,30 @@ class CourseCreateSerializer(serializers.ModelSerializer): course=course, url=c['data']['url'], ) + elif c['type'] == 'images': + if 'id' in c['data'] and c['data']['id']: + g = Gallery.objects.get(id=c['data']['id']) + g.position = c['data']['position'] + g.title = c['data']['title'] + g.save() + if 'images' in c['data']: + for image in c['data']['images']: + gi = GalleryImage.objects.create( + gallery=g, + img=ImageObject.objects.get(id=image['id']) + ) + else: + g = Gallery.objects.create( + position=c['data']['position'], + title=c['data']['title'], + ) + if 'images' in c['data']: + for image in c['data']['images']: + gi = GalleryImage.objects.create( + gallery=g, + img=ImageObject.objects.get(id=image['id']), + ) + for material in materials: if 'id' in material and material['id']: m = Material.objects.get(id=material['id']) @@ -195,22 +219,26 @@ class CourseCreateSerializer(serializers.ModelSerializer): if 'id' in gallery and gallery['id']: g = Gallery.objects.get(id=gallery['id']) g.title = gallery.get('title', g.title) + g.course = course + g.position = 0 g.save() else: g = Gallery.objects.create( - title=gallery.get('title', '') + title=gallery.get('title', ''), + course=course, + position=0, ) if 'images' in gallery: - for i in gallery['images']: - if 'id' in i and i['id']: - gi = GalleryImage.objects.get(id=i['id']) + for image in gallery['images']: + if 'id' in image and image['id']: + gi = GalleryImage.objects.get(id=image['id']) gi.gallery = g - gi.img = i['img'] + gi.img = image['img'] gi.save() else: gi = GalleryImage.objects.create( gallery=g, - img=i['img'], + img=image['img'], ) course.gallery = g course.save() @@ -286,14 +314,14 @@ class LessonCreateSerializer(serializers.ModelSerializer): ) elif c['type'] == 'image': if 'id' in c['data'] and c['data']['id']: - i = Image.objects.get(id=c['data']['id']) - i.position = c['data']['position'] - i.title = c['data']['title'] - i.lesson = lesson - i.img = ImageObject.objects.get(id=c['data']['img']) - i.save() + image = Image.objects.get(id=c['data']['id']) + image.position = c['data']['position'] + image.title = c['data']['title'] + image.lesson = lesson + image.img = ImageObject.objects.get(id=c['data']['img']) + image.save() else: - i = Image.objects.create( + image = Image.objects.create( position=c['data']['position'], title=c['data']['title'], lesson=lesson, @@ -331,6 +359,29 @@ class LessonCreateSerializer(serializers.ModelSerializer): lesson=lesson, url=c['data']['url'], ) + elif c['type'] == 'images': + if 'id' in c['data'] and c['data']['id']: + g = Gallery.objects.get(id=c['data']['id']) + g.position = c['data']['position'] + g.title = c['data']['title'] + g.save() + if 'images' in c['data']: + for image in c['data']['images']: + gi = GalleryImage.objects.create( + gallery=g, + img=ImageObject.objects.get(id=image['id']), + ) + else: + g = Gallery.objects.create( + position=c['data']['position'], + title=c['data']['title'], + ) + if 'images' in c['data']: + for image in c['data']['images']: + gi = GalleryImage.objects.create( + gallery=g, + img=ImageObject.objects.get(id=image['id']), + ) def create(self, validated_data): content = validated_data.pop('content', []) From b9915d2e2be0c16b277b640e42686674a3b34a4a Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:05:57 +0300 Subject: [PATCH 12/14] Fix gallery admin --- apps/content/admin.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/content/admin.py b/apps/content/admin.py index c30a3a38..34b19204 100644 --- a/apps/content/admin.py +++ b/apps/content/admin.py @@ -48,6 +48,11 @@ class VideoAdmin(ContentChildAdmin): base_model = Video +@admin.register(Gallery) +class GalleryAdmin(ContentChildAdmin): + base_model = Gallery + + @admin.register(Content) class ContentAdmin(PolymorphicParentModelAdmin): base_model = Content @@ -55,15 +60,11 @@ class ContentAdmin(PolymorphicParentModelAdmin): Image, Text, ImageText, - Video + Video, + GalleryAdmin, ) -@admin.register(Gallery) -class GalleryAdmin(admin.ModelAdmin): - pass - - @admin.register(GalleryImage) class GalleryImageAdmin(admin.ModelAdmin): pass From 6e1073dd2c760a8ef2dcae4fbf19a8b301587b6b Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:46:07 +0300 Subject: [PATCH 13/14] Add type to serializers --- api/v1/serializers/content.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/api/v1/serializers/content.py b/api/v1/serializers/content.py index e1159b2e..3743371f 100644 --- a/api/v1/serializers/content.py +++ b/api/v1/serializers/content.py @@ -55,6 +55,7 @@ class ImageObjectSerializer(serializers.ModelSerializer): class ImageCreateSerializer(serializers.ModelSerializer): + type = serializers.SerializerMethodField() class Meta: model = Image @@ -65,22 +66,28 @@ class ImageCreateSerializer(serializers.ModelSerializer): 'title', 'position', 'img', + 'type', 'created_at', 'update_at', ) read_only_fields = ( 'id', + 'type', 'created_at', 'update_at', ) + def get_type(self, object): + return 'image' + class ImageSerializer(ImageCreateSerializer): img = ImageObjectSerializer() class TextCreateSerializer(serializers.ModelSerializer): + type = serializers.SerializerMethodField() class Meta: model = Text @@ -100,12 +107,16 @@ class TextCreateSerializer(serializers.ModelSerializer): 'update_at', ) + def get_type(self, object): + return 'text' + class TextSerializer(TextCreateSerializer): pass class ImageTextCreateSerializer(serializers.ModelSerializer): + type = serializers.SerializerMethodField() class Meta: model = ImageText @@ -127,12 +138,16 @@ class ImageTextCreateSerializer(serializers.ModelSerializer): 'update_at', ) + def get_type(self, object): + return 'image-text' + class ImageTextSerializer(ImageTextCreateSerializer): img = ImageObjectSerializer() class VideoCreateSerializer(serializers.ModelSerializer): + type = serializers.SerializerMethodField() class Meta: model = Video @@ -152,6 +167,9 @@ class VideoCreateSerializer(serializers.ModelSerializer): 'update_at', ) + def get_type(self, object): + return 'video' + class VideoSerializer(VideoCreateSerializer): pass @@ -181,6 +199,7 @@ class GalleryImageSerializer(GalleryImageCreateSerializer): class GallerySerializer(serializers.ModelSerializer): + type = serializers.SerializerMethodField() gallery_images = GalleryImageSerializer(many=True) class Meta: @@ -202,6 +221,9 @@ class GallerySerializer(serializers.ModelSerializer): 'update_at', ) + def get_type(self, object): + return 'images' + class ContentSerializer(serializers.ModelSerializer): From 995749ef049c08fd78c5bb02937d6f6fcfb6ae88 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Mon, 12 Feb 2018 09:48:15 +0300 Subject: [PATCH 14/14] Fix serializer fields --- api/v1/serializers/content.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/v1/serializers/content.py b/api/v1/serializers/content.py index 3743371f..c01a2c65 100644 --- a/api/v1/serializers/content.py +++ b/api/v1/serializers/content.py @@ -97,12 +97,14 @@ class TextCreateSerializer(serializers.ModelSerializer): 'lesson', 'title', 'position', + 'type', 'created_at', 'update_at', ) + ('txt',) read_only_fields = ( 'id', + 'type', 'created_at', 'update_at', ) @@ -128,12 +130,14 @@ class ImageTextCreateSerializer(serializers.ModelSerializer): 'position', 'img', 'txt', + 'type', 'created_at', 'update_at', ) read_only_fields = ( 'id', + 'type', 'created_at', 'update_at', ) @@ -157,12 +161,14 @@ class VideoCreateSerializer(serializers.ModelSerializer): 'lesson', 'title', 'position', + 'type', 'created_at', 'update_at', ) + ('url',) read_only_fields = ( 'id', + 'type', 'created_at', 'update_at', ) @@ -211,12 +217,14 @@ class GallerySerializer(serializers.ModelSerializer): 'title', 'position', 'gallery_images', + 'type', 'created_at', 'update_at', ) read_only_fields = ( 'id', + 'type', 'created_at', 'update_at', )