You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
10 KiB
305 lines
10 KiB
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, 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
|
|
from .filters import CourseFilter
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
@login_required
|
|
@csrf_exempt
|
|
@require_http_methods(['POST'])
|
|
def likes(request, course_id):
|
|
try:
|
|
course = Course.objects.prefetch_related('likes').get(id=course_id)
|
|
except Course.DoesNotExist:
|
|
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():
|
|
is_liked = False
|
|
for _course in course_user_likes.all():
|
|
course.likes.remove(_course)
|
|
course_user_likes.delete()
|
|
else:
|
|
is_liked = True
|
|
course.likes.add(Like.objects.create(user=request.user))
|
|
count = course.likes.count()
|
|
return JsonResponse({
|
|
"success": True,
|
|
"likes_count": count,
|
|
"is_liked": is_liked,
|
|
})
|
|
|
|
|
|
@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', 0)
|
|
comment = request.POST.get('comment', '')
|
|
if not comment:
|
|
return JsonResponse({
|
|
'success': False,
|
|
'errors': ['Comment can not be empty']
|
|
}, status=400)
|
|
|
|
if not int(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,
|
|
parent=_coursecomment,
|
|
)
|
|
ctx = {'node': coursecomment, 'user': request.user}
|
|
html = loader.render_to_string('course/blocks/comment.html', ctx)
|
|
return JsonResponse({
|
|
'success': True,
|
|
'comment': html,
|
|
})
|
|
|
|
|
|
@login_required
|
|
@csrf_exempt
|
|
@require_http_methods(['POST'])
|
|
def lessoncomment(request, lesson_id):
|
|
try:
|
|
lesson = Lesson.objects.get(id=lesson_id)
|
|
except Lesson.DoesNotExist:
|
|
return JsonResponse({
|
|
'success': False,
|
|
'errors': ['Lesson with id f{lesson_id} not found']
|
|
}, status=400)
|
|
else:
|
|
reply_to = request.POST.get('reply_id', 0)
|
|
comment = request.POST.get('comment', '')
|
|
if not comment:
|
|
return JsonResponse({
|
|
'success': False,
|
|
'errors': ['Comment can not be empty']
|
|
}, status=400)
|
|
|
|
if not int(reply_to):
|
|
lessoncomment = LessonComment.objects.create(
|
|
author=request.user,
|
|
content=comment,
|
|
lesson=lesson,
|
|
)
|
|
else:
|
|
try:
|
|
_lessoncomment = LessonComment.objects.get(id=reply_to)
|
|
except LessonComment.DoesNotExist:
|
|
return JsonResponse({
|
|
'success': False,
|
|
'errors': ['LessonComment with id f{reply_to} not found']
|
|
}, status=400)
|
|
else:
|
|
lessoncomment = LessonComment.objects.create(
|
|
author=request.user,
|
|
content=comment,
|
|
lesson=lesson,
|
|
parent=_lessoncomment,
|
|
)
|
|
ctx = {'node': lessoncomment, 'user': request.user}
|
|
html = loader.render_to_string('course/blocks/comment.html', ctx)
|
|
return JsonResponse({
|
|
'success': True,
|
|
'comment': html,
|
|
})
|
|
|
|
|
|
@method_decorator(login_required, name='dispatch')
|
|
class CourseOnModerationView(TemplateView):
|
|
template_name = 'course/course_on_moderation.html'
|
|
|
|
|
|
@method_decorator(login_required, name='dispatch')
|
|
class CourseEditView(TemplateView):
|
|
template_name = 'course/course_edit.html'
|
|
|
|
def get(self, request, pk=None):
|
|
drafts = Course.objects.filter(author=request.user, status=Course.DRAFT)
|
|
if pk:
|
|
self.object = get_object_or_404(Course, pk=pk)
|
|
elif drafts.exists():
|
|
self.object = drafts.last()
|
|
else:
|
|
self.object = Course.objects.create()
|
|
return super().get(request)
|
|
|
|
def get_context_data(self):
|
|
context = super().get_context_data()
|
|
if self.object:
|
|
context['course'] = self.object
|
|
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):
|
|
response = super().get(request, *args, **kwargs)
|
|
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
|
|
return response
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['next'] = self.request.GET.get('next', None)
|
|
return context
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset().select_related(
|
|
'author', 'category',
|
|
).prefetch_related(
|
|
'likes', 'materials', 'content',
|
|
)
|
|
return queryset
|
|
|
|
|
|
class CoursesView(ListView):
|
|
model = Course
|
|
context_object_name = 'course_items'
|
|
paginate_by = 6
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.object_list = self.get_queryset()
|
|
allow_empty = self.get_allow_empty()
|
|
if request.is_ajax():
|
|
context = self.get_context_data()
|
|
template_name = self.get_template_names()
|
|
html = loader.render_to_string(
|
|
template_name, context, request=request)
|
|
is_paginated = context.get('is_paginated')
|
|
if is_paginated:
|
|
page_obj = context.get('page_obj')
|
|
prev_url = request.path + '?page=' + \
|
|
str(page_obj.previous_page_number()
|
|
) if page_obj.has_previous() else None
|
|
next_url = request.path + '?page=' + \
|
|
str(page_obj.next_page_number()
|
|
) if page_obj.has_next() else None
|
|
else:
|
|
prev_url = None
|
|
next_url = None
|
|
return JsonResponse({
|
|
'success': True,
|
|
'content': html,
|
|
'prev_url': prev_url,
|
|
'next_url': next_url,
|
|
})
|
|
else:
|
|
return super().get(request, args, kwargs)
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset().select_related(
|
|
'author', 'category', 'cover',
|
|
).prefetch_related(
|
|
'likes', 'materials', 'content',
|
|
).filter(status=Course.PUBLISHED)
|
|
filtered = CourseFilter(self.request.GET, queryset=queryset)
|
|
return filtered.qs
|
|
|
|
def get_context_data(self):
|
|
context = super().get_context_data()
|
|
filtered = CourseFilter(self.request.GET)
|
|
context.update(filtered.data)
|
|
return context
|
|
|
|
def get_template_names(self):
|
|
if self.request.is_ajax():
|
|
return 'course/course_items.html'
|
|
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
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['next'] = self.request.GET.get('next', None)
|
|
context['next_lesson'] = self.request.GET.get('next_lesson', None)
|
|
return context
|
|
|
|
|
|
class SearchView(CoursesView):
|
|
template_name = 'course/result.html'
|
|
|
|
def get_queryset(self):
|
|
search_query = self.request.GET.get('q', None)
|
|
queryset = super().get_queryset()
|
|
if search_query:
|
|
query = Q(title__icontains=search_query) | Q(
|
|
short_description__icontains=search_query)
|
|
queryset = queryset.filter(query)
|
|
else:
|
|
queryset = queryset.none()
|
|
return queryset
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['q'] = self.request.GET.get('q', None) or ''
|
|
return context
|
|
if 'is_paginated' in context and context['is_paginated']:
|
|
page_obj = context.get('page_obj')
|
|
context['page'] = page_obj.number
|
|
context['next_page'] = str(
|
|
page_obj.next_page_number()) if page_obj.has_next() else None
|
|
else:
|
|
context['page'] = 1
|
|
context['next_page'] = None
|
|
return context
|
|
|
|
def get_template_names(self):
|
|
if self.request.is_ajax():
|
|
return 'course/course_items.html'
|
|
return 'course/result.html'
|
|
|