From 319a1070afb1adc62b15a134eb14d534946d938d Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 30 Jan 2018 11:06:26 +0300 Subject: [PATCH 1/6] Add detail view for lesson --- apps/course/views.py | 8 +++++++- project/urls.py | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/course/views.py b/apps/course/views.py index 0718d003..466f9b54 100644 --- a/apps/course/views.py +++ b/apps/course/views.py @@ -4,7 +4,7 @@ from django.template import loader from django.views.generic import View, DetailView, ListView from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods -from .models import Course, Like +from .models import Course, Like, Lesson from .filters import CourseFilter @@ -81,3 +81,9 @@ class CoursesView(ListView): if self.request.is_ajax(): return 'course/course_items.html' return 'course/courses.html' + + +class LessonView(DetailView): + model = Lesson + context_object_name = 'lesson' + template_name = 'course/lesson.html' diff --git a/project/urls.py b/project/urls.py index 8bf2d905..495632dd 100644 --- a/project/urls.py +++ b/project/urls.py @@ -18,7 +18,7 @@ from django.urls import path, include from django.views.generic import TemplateView from django.conf import settings -from apps.course.views import CoursesView, likes, CourseView +from apps.course.views import CoursesView, likes, CourseView, LessonView urlpatterns = [ path('admin/', admin.site.urls), @@ -26,6 +26,7 @@ urlpatterns = [ path('courses/', CoursesView.as_view(), name='courses'), path('course//', CourseView.as_view(), name='course'), path('course//like', likes, name='likes'), + path('lesson//', LessonView.as_view(), name='lesson'), path('', TemplateView.as_view(template_name="templates/lilcity/main.html"), name='index'), ] From cc61b14d1553c1f0c43137460e9e461d2ee04509 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 30 Jan 2018 11:14:47 +0300 Subject: [PATCH 2/6] Move parent field from Comment to own comment types --- .../migrations/0017_auto_20180130_0810.py | 29 +++++++++++++++++++ apps/course/models.py | 3 +- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 apps/course/migrations/0017_auto_20180130_0810.py diff --git a/apps/course/migrations/0017_auto_20180130_0810.py b/apps/course/migrations/0017_auto_20180130_0810.py new file mode 100644 index 00000000..9aec43d5 --- /dev/null +++ b/apps/course/migrations/0017_auto_20180130_0810.py @@ -0,0 +1,29 @@ +# Generated by Django 2.0.1 on 2018-01-30 08:10 + +from django.db import migrations +import django.db.models.deletion +import mptt.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0016_auto_20180129_1756'), + ] + + operations = [ + migrations.RemoveField( + model_name='comment', + name='parent', + ), + migrations.AddField( + model_name='coursecomment', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.CourseComment'), + ), + migrations.AddField( + model_name='lessoncomment', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.LessonComment'), + ), + ] diff --git a/apps/course/models.py b/apps/course/models.py index 0b851950..9fa9c2c0 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -121,7 +121,6 @@ class Material(models.Model): 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='') @@ -141,6 +140,7 @@ class Comment(MPTTModel): class CourseComment(Comment): + parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.PROTECT) course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='comments') class Meta: @@ -149,6 +149,7 @@ class CourseComment(Comment): class LessonComment(Comment): + parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.PROTECT) lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, related_name='comments') class Meta: From 92b7f502e940c9a741a7ef67d26f611934443ee4 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 30 Jan 2018 11:20:46 +0300 Subject: [PATCH 3/6] Unification comment block --- apps/course/templates/course/blocks/comments.html | 2 +- apps/course/templates/course/course.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/course/templates/course/blocks/comments.html b/apps/course/templates/course/blocks/comments.html index 253c501b..55e7f615 100644 --- a/apps/course/templates/course/blocks/comments.html +++ b/apps/course/templates/course/blocks/comments.html @@ -1,7 +1,7 @@ {% load static %} {% load mptt_tags %} -{% recursetree course.comments.all %} +{% recursetree object.comments.all %}
{% if node.author.photo %} diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index 73e75a3f..57d9bc00 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -201,7 +201,7 @@
- {% include "./blocks/comments.html" with course=course %} + {% include "./blocks/comments.html" with object=course %}
From 0a19ce76a5e4b04ff9941d90a101c60ca0cc99ea Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 30 Jan 2018 11:31:10 +0300 Subject: [PATCH 4/6] LIL-109. Add simple template for lesson --- apps/course/templates/course/lesson.html | 131 +++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 apps/course/templates/course/lesson.html diff --git a/apps/course/templates/course/lesson.html b/apps/course/templates/course/lesson.html new file mode 100644 index 00000000..5a76111d --- /dev/null +++ b/apps/course/templates/course/lesson.html @@ -0,0 +1,131 @@ +{% extends "templates/lilcity/index.html" %} +{% load static %} +{% block title %}{{ lesson.title }} - {{ block.super }}{% endblock title %} + +{% block content %} + +
+
+
Примеры техники
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
Задавайте вопросы:
+
+
+
+ +
+
+
+ +
+ +
+
+
+ {% include "./blocks/comments.html" with object=lesson %} +
+
+
+
+
+
+ +
+
+{% endblock content %} From 5e7057252dd07614320d1ce3560b7857eef0a678 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 30 Jan 2018 13:39:38 +0300 Subject: [PATCH 5/6] Split comments template --- .../templates/course/blocks/comment.html | 25 +++++++++++++++++ .../templates/course/blocks/comments.html | 27 +------------------ 2 files changed, 26 insertions(+), 26 deletions(-) create mode 100644 apps/course/templates/course/blocks/comment.html diff --git a/apps/course/templates/course/blocks/comment.html b/apps/course/templates/course/blocks/comment.html new file mode 100644 index 00000000..cbb199f4 --- /dev/null +++ b/apps/course/templates/course/blocks/comment.html @@ -0,0 +1,25 @@ +{% load static %} + +
+ {% if node.author.photo %} +
+ +
+ {% else %} +
+ +
+ {% endif %} +
+
+
+ {{ node.author.get_full_name }} + {{ node.created_at_humanize }} +
+
{{ node.content }}
+
+
+ +
+
+
\ No newline at end of file diff --git a/apps/course/templates/course/blocks/comments.html b/apps/course/templates/course/blocks/comments.html index 55e7f615..c762ebc5 100644 --- a/apps/course/templates/course/blocks/comments.html +++ b/apps/course/templates/course/blocks/comments.html @@ -1,30 +1,5 @@ -{% load static %} {% load mptt_tags %} {% recursetree object.comments.all %} - -
- {% if node.author.photo %} -
- -
- {% else %} -
- -
- {% endif %} -
-
-
- {{ node.author.get_full_name }} - {{ node.created_at_humanize }} -
-
{{ node.content }}
-
-
- -
-
-
- +{% include './comment.html' %} {{ children }} {% endrecursetree %} \ No newline at end of file From e7962bb00d575059de002c6bf0a72ee752f26388 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 30 Jan 2018 13:40:11 +0300 Subject: [PATCH 6/6] Add comments handler --- apps/course/views.py | 57 ++++++++++++++++++++++++++++++++++++++++---- project/urls.py | 3 ++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/apps/course/views.py b/apps/course/views.py index 466f9b54..6521837f 100644 --- a/apps/course/views.py +++ b/apps/course/views.py @@ -1,10 +1,10 @@ from django.contrib.auth.decorators import login_required from django.http import JsonResponse -from django.template import loader -from django.views.generic import View, DetailView, ListView +from django.template import loader, Context, Template +from django.views.generic import View, CreateView, DetailView, ListView from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods -from .models import Course, Like, Lesson +from .models import Course, Like, Lesson, CourseComment, LessonComment from .filters import CourseFilter @@ -18,7 +18,7 @@ def likes(request, course_id): return JsonResponse({ 'success': False, 'errors': ['Course with id f{cource_id} not found'] - }) + }, status=400) else: course_user_likes = course.likes.filter(user=request.user) if course_user_likes.exists(): @@ -37,6 +37,55 @@ def likes(request, course_id): }) +@login_required +@csrf_exempt +@require_http_methods(['POST']) +def coursecomment(request, course_id): + try: + course = Course.objects.get(id=course_id) + except Course.DoesNotExist: + return JsonResponse({ + 'success': False, + 'errors': ['Course with id f{cource_id} not found'] + }, status=400) + else: + reply_to = request.POST.get('reply_id', None) + comment = request.POST.get('comment', '') + if not comment: + return JsonResponse({ + 'success': False, + 'errors': ['Comment can not be empty'] + }, status=400) + + if not reply_to: + coursecomment = CourseComment.objects.create( + author=request.user, + content=comment, + course=course, + ) + else: + try: + _coursecomment = CourseComment.objects.get(id=reply_to) + except CourseComment.DoesNotExist: + return JsonResponse({ + 'success': False, + 'errors': ['CourseComment with id f{reply_to} not found'] + }, status=400) + else: + coursecomment = CourseComment.objects.create( + author=request.user, + content=comment, + course=course, + parrent=_coursecomment, + ) + ctx = {'node': coursecomment} + html = loader.render_to_string('course/blocks/comment.html', ctx) + return JsonResponse({ + 'success': True, + 'comment': html, + }) + + class CourseView(DetailView): model = Course context_object_name = 'course' diff --git a/project/urls.py b/project/urls.py index 495632dd..0822252b 100644 --- a/project/urls.py +++ b/project/urls.py @@ -18,7 +18,7 @@ from django.urls import path, include from django.views.generic import TemplateView from django.conf import settings -from apps.course.views import CoursesView, likes, CourseView, LessonView +from apps.course.views import CoursesView, likes, coursecomment, CourseView, LessonView urlpatterns = [ path('admin/', admin.site.urls), @@ -26,6 +26,7 @@ urlpatterns = [ path('courses/', CoursesView.as_view(), name='courses'), path('course//', CourseView.as_view(), name='course'), path('course//like', likes, name='likes'), + path('course//comment', coursecomment, name='coursecomment'), path('lesson//', LessonView.as_view(), name='lesson'), path('', TemplateView.as_view(template_name="templates/lilcity/main.html"), name='index'), ]