From 35d21c4594c779089d01eca3175b24dab3f5c2ec Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 12:37:03 +0300 Subject: [PATCH 01/11] LIL-237. Add video counter --- apps/course/models.py | 20 ++++++++++++-------- apps/course/templates/course/course.html | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/apps/course/models.py b/apps/course/models.py index be1637a3..01d065cd 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -11,7 +11,7 @@ from project.mixins import BaseModel, DeactivatedMixin from .manager import CategoryQuerySet -from apps.content.models import ImageObject, Gallery +from apps.content.models import ImageObject, Gallery, Video User = get_user_model() @@ -84,6 +84,14 @@ class Course(BaseModel, DeactivatedMixin): 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'] + + def __str__(self): + return str(self.id) + ' ' + self.title + def save(self, *args, **kwargs): if not self.slug: self.slug = slugify( @@ -126,13 +134,9 @@ class Course(BaseModel, DeactivatedMixin): return True return False - def __str__(self): - return str(self.id) + ' ' + self.title - - class Meta: - verbose_name = 'Курс' - verbose_name_plural = 'Курсы' - ordering = ['-created_at'] + @property + def count_videos_in_lessons(self): + return Video.objects.filter(lesson__in=self.lessons.all()).count() class Category(models.Model): diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index 93e3b235..6c84a31f 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -126,7 +126,7 @@ -
12 видео
+
{{ course.count_videos_in_lessons }} видео
From 0bac3bcb7ce281b80e7efad244acd84d633e54a5 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 12:38:17 +0300 Subject: [PATCH 02/11] LIL-237. Add publicate date --- apps/course/templates/course/course.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index 6c84a31f..058bab04 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -100,7 +100,7 @@ -
15 ноября
+
{{ course.created_at | date:"d F Yг." }}
From ca06f27abd6686dbdc51b353d65e506835140221 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 12:39:52 +0300 Subject: [PATCH 03/11] LIL-237. Remove materials block --- apps/course/templates/course/course.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index 058bab04..7b4fc854 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -233,7 +233,7 @@
-
+{% comment %}
Материалы, которые понадобятся
@@ -256,7 +256,7 @@ {% endfor %}
-
+
{% endcomment %} {% endif %}
From 279a735dab5c740894e818b96abd81cd6005fa51 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 12:50:39 +0300 Subject: [PATCH 04/11] LIL-237. Fix cover --- apps/course/templates/course/_items.html | 2 +- apps/course/templates/course/course.html | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/course/templates/course/_items.html b/apps/course/templates/course/_items.html index 8c8dc4ac..407526ca 100644 --- a/apps/course/templates/course/_items.html +++ b/apps/course/templates/course/_items.html @@ -8,7 +8,7 @@ > {% if course.cover %} - + {% else %} {% endif %} diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index 7b4fc854..d563e8c1 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -142,7 +142,11 @@
- + {% if course.cover %} + + {% else %} + + {% endif %} {% if course.is_deferred_start %}
Курс начнется:
@@ -263,7 +267,10 @@ {% include "course/content/gallery.html" with results=True %}
-
+
ПЕРСОНАЖИ
@@ -326,7 +333,7 @@
-
15 ноября
+
{{ course.created_at | date:"d F Yг." }}
From 51b03294c0c61df64936c853c96a604813a4b7b5 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 12:59:28 +0300 Subject: [PATCH 05/11] LIL-237. Clear empty section --- apps/course/templates/course/course.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index d563e8c1..a99f3987 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -205,7 +205,7 @@
{% endfor %} -{% if user.is_authenticated %} +{% if user.is_authenticated and course.lessons.exists %}
@@ -262,11 +262,13 @@
{% endcomment %} {% endif %} +{% if course.gallery %}
{% include "course/content/gallery.html" with results=True %}
+{% endif %}
Date: Wed, 14 Feb 2018 13:29:07 +0300 Subject: [PATCH 06/11] LIL-237. Check user perms in course detail view --- apps/course/views.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/course/views.py b/apps/course/views.py index b41115ff..6efa9f88 100644 --- a/apps/course/views.py +++ b/apps/course/views.py @@ -1,6 +1,7 @@ +from django.contrib.auth import get_user_model from django.contrib.auth.decorators import login_required from django.db.models import Q -from django.http import JsonResponse +from django.http import JsonResponse, Http404 from django.shortcuts import get_object_or_404 from django.template import loader, Context, Template from django.views.generic import View, CreateView, DetailView, ListView, TemplateView @@ -9,6 +10,8 @@ from django.views.decorators.http import require_http_methods from .models import Course, Like, Lesson, CourseComment, LessonComment from .filters import CourseFilter +User = get_user_model() + @login_required @csrf_exempt @@ -159,6 +162,14 @@ class CourseView(DetailView): context_object_name = 'course' template_name = 'course/course.html' + def get(self, request, *args, **kwargs): + request = super().get(request, *args, **kwargs) + if (self.object != Course.PUBLISHED and + (request.user.role not in [User.AUTHOR_ROLE, User.ADMIN_ROLE] or + object.author != request.user)): + raise Http404 + return request + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['next'] = self.request.GET.get('next', None) From 0347852253ae127eb3b65d8aa6970fb17022bef1 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 13:38:29 +0300 Subject: [PATCH 07/11] LIL-237. Check auth in course detail view --- apps/course/views.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/course/views.py b/apps/course/views.py index 6efa9f88..48e22845 100644 --- a/apps/course/views.py +++ b/apps/course/views.py @@ -5,6 +5,7 @@ from django.http import JsonResponse, Http404 from django.shortcuts import get_object_or_404 from django.template import loader, Context, Template from django.views.generic import View, CreateView, DetailView, ListView, TemplateView +from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods from .models import Course, Like, Lesson, CourseComment, LessonComment @@ -157,18 +158,19 @@ class CourseEditView(TemplateView): return context +@method_decorator(login_required, name='dispatch') class CourseView(DetailView): model = Course context_object_name = 'course' template_name = 'course/course.html' def get(self, request, *args, **kwargs): - request = super().get(request, *args, **kwargs) + response = super().get(request, *args, **kwargs) if (self.object != Course.PUBLISHED and (request.user.role not in [User.AUTHOR_ROLE, User.ADMIN_ROLE] or - object.author != request.user)): + self.object.author != request.user)): raise Http404 - return request + return response def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) From 70c27872283e2fc7098c438dc54eacc2b616c8a0 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 13:41:58 +0300 Subject: [PATCH 08/11] LIL-237. Check user perms in lesson detail view --- apps/course/templates/course/course.html | 2 +- apps/course/views.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index a99f3987..51f12405 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -212,7 +212,7 @@
Содержание курса
{% for lesson in course.lessons.all %} - +
{{ lesson.title }}
diff --git a/apps/course/views.py b/apps/course/views.py index 48e22845..da8af471 100644 --- a/apps/course/views.py +++ b/apps/course/views.py @@ -166,7 +166,7 @@ class CourseView(DetailView): def get(self, request, *args, **kwargs): response = super().get(request, *args, **kwargs) - if (self.object != Course.PUBLISHED and + if (self.object.status != Course.PUBLISHED and (request.user.role not in [User.AUTHOR_ROLE, User.ADMIN_ROLE] or self.object.author != request.user)): raise Http404 @@ -241,11 +241,20 @@ class CoursesView(ListView): return 'course/courses.html' +@method_decorator(login_required, name='dispatch') class LessonView(DetailView): model = Lesson context_object_name = 'lesson' template_name = 'course/lesson.html' + def get(self, request, *args, **kwargs): + response = super().get(request, *args, **kwargs) + if (self.object.course.status != Course.PUBLISHED and + (request.user.role not in [User.AUTHOR_ROLE, User.ADMIN_ROLE] or + self.object.course.author != request.user)): + raise Http404 + return response + class SearchView(CoursesView): template_name = 'course/result.html' From 585323e357319f7551e976b187ff14c3d33115b4 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 14:37:57 +0300 Subject: [PATCH 09/11] Fix update course --- api/v1/serializers/course.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index ac14f50a..4c6814a8 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -138,7 +138,7 @@ class CourseCreateSerializer(DispatchContentMixin, materials = validated_data.pop('materials', []) gallery = validated_data.pop('gallery', {}) author = validated_data.get('author', None) - if not author: + if not instance.author or not author: validated_data['author'] = self.context['request'].user course = super().update(instance, validated_data) self.dispatch_materials(course, materials) From 90c1d350f4a97cc9770209a3918f56298acf1d0e Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Wed, 14 Feb 2018 16:36:56 +0300 Subject: [PATCH 10/11] Update Course model --- .../migrations/0032_auto_20180214_1336.py | 28 +++++++++++++++++++ apps/course/models.py | 7 +++-- 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 apps/course/migrations/0032_auto_20180214_1336.py diff --git a/apps/course/migrations/0032_auto_20180214_1336.py b/apps/course/migrations/0032_auto_20180214_1336.py new file mode 100644 index 00000000..9da8cb90 --- /dev/null +++ b/apps/course/migrations/0032_auto_20180214_1336.py @@ -0,0 +1,28 @@ +# Generated by Django 2.0.2 on 2018-02-14 13:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0031_auto_20180213_0906'), + ] + + operations = [ + migrations.AlterField( + model_name='course', + name='short_description', + field=models.TextField(db_index=True, default='', verbose_name='Краткое описание курса'), + ), + migrations.AlterField( + model_name='course', + name='status', + field=models.PositiveSmallIntegerField(choices=[(0, 'Draft'), (1, 'Pending'), (2, 'Published'), (3, 'Archived'), (4, 'Denied')], default=0, verbose_name='Статус'), + ), + migrations.AlterField( + model_name='course', + name='title', + field=models.CharField(db_index=True, default='', max_length=100, verbose_name='Название курса'), + ), + ] diff --git a/apps/course/models.py b/apps/course/models.py index 01d065cd..1ed76ca8 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -45,10 +45,11 @@ class Course(BaseModel, DeactivatedMixin): max_length=100, unique=True, db_index=True, ) author = models.ForeignKey( - User, on_delete=models.SET_NULL, null=True, blank=True) - title = models.CharField('Название курса', max_length=100, db_index=True) + User, on_delete=models.SET_NULL, null=True, blank=True + ) + title = models.CharField('Название курса', default='', max_length=100, db_index=True) short_description = models.TextField( - 'Краткое описание курса', db_index=True + 'Краткое описание курса', default='', db_index=True ) from_author = models.TextField( 'От автора', default='', null=True, blank=True From b0e7491ff4ea34dd1ce905e71f1c97c8a07f251a Mon Sep 17 00:00:00 2001 From: Sanasol Date: Wed, 14 Feb 2018 21:05:43 +0700 Subject: [PATCH 11/11] select fix, image remove --- web/src/components/blocks/BlockImages.vue | 15 ++++++++++++++- web/src/components/inputs/LilSelect.vue | 4 ++-- web/src/js/modules/api.js | 7 +++++++ web/src/sass/_common.sass | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/web/src/components/blocks/BlockImages.vue b/web/src/components/blocks/BlockImages.vue index e601f9ed..0d8b6017 100644 --- a/web/src/components/blocks/BlockImages.vue +++ b/web/src/components/blocks/BlockImages.vue @@ -25,8 +25,13 @@