From 2a9f81cb32acfd7a2efc18f58c4529b39ce4061b Mon Sep 17 00:00:00 2001 From: CruiseDevice Date: Sat, 11 Apr 2020 17:45:31 +0530 Subject: Discussion forum for a course --- yaksh/admin.py | 4 +- yaksh/models.py | 38 +++++++++++++++++ yaksh/templates/yaksh/course_forum.html | 68 ++++++++++++++++++++++++++++++ yaksh/templates/yaksh/course_modules.html | 1 + yaksh/templates/yaksh/thread_comments.html | 46 ++++++++++++++++++++ yaksh/urls.py | 2 + yaksh/views.py | 45 +++++++++++++++++++- 7 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 yaksh/templates/yaksh/course_forum.html create mode 100644 yaksh/templates/yaksh/thread_comments.html (limited to 'yaksh') diff --git a/yaksh/admin.py b/yaksh/admin.py index 9c36a98..4489ffc 100644 --- a/yaksh/admin.py +++ b/yaksh/admin.py @@ -1,7 +1,7 @@ from yaksh.models import Question, Quiz, QuestionPaper, Profile from yaksh.models import (TestCase, StandardTestCase, StdIOBasedTestCase, Course, AnswerPaper, CourseStatus, LearningModule, - Lesson + Lesson, Thread, Comment ) from django.contrib import admin @@ -48,6 +48,8 @@ class QuizAdmin(admin.ModelAdmin): admin.site.register(Profile, ProfileAdmin) admin.site.register(Question) admin.site.register(TestCase) +admin.site.register(Thread) +admin.site.register(Comment) admin.site.register(StandardTestCase) admin.site.register(StdIOBasedTestCase) admin.site.register(Course, CourseAdmin) diff --git a/yaksh/models.py b/yaksh/models.py index 52a0414..83c644a 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals, division from datetime import datetime, timedelta +import uuid import json import random import ruamel.yaml @@ -2633,3 +2634,40 @@ class TestCaseOrder(models.Model): order = models.TextField() ############################################################################## +class Thread(models.Model): + uid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False) + creator = models.ForeignKey(User, on_delete=models.CASCADE) + title = models.CharField(max_length=200) + description = models.TextField() + course = models.ForeignKey(Course, + on_delete=models.CASCADE, related_name='thread') + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) + # image = models.ImageField(upload_to='images/%y/%m/%d', blank=True) + + def __str__(self): + return self.title + + def get_last_comment(self): + return self.comment.last() + + def get_comments_count(self): + return self.comment.count() + +############################################################################## +class Comment(models.Model): + uid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False) + user = models.ForeignKey(User, on_delete=models.CASCADE) + thread = models.ForeignKey(Thread, + on_delete=models.CASCADE, + related_name='comment') + body = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) + active = models.BooleanField(default=True) #make it false if improper comment + # image = models.ImageField(upload_to='images/%y/%m/%d', blank=True) + + + def __str__(self): + return 'Comment by {0}: \n {1}'.format(self.user.username, + self.thread.title) diff --git a/yaksh/templates/yaksh/course_forum.html b/yaksh/templates/yaksh/course_forum.html new file mode 100644 index 0000000..b0c7024 --- /dev/null +++ b/yaksh/templates/yaksh/course_forum.html @@ -0,0 +1,68 @@ +{% extends "user.html" %} +{% load humanize %} +{% block title %} + {{course.name}}: Discussion Forum +{% endblock title %} +{% block content %} +
+
+

{{course.name}}

+
Discussion Forum
+
+
+ +
+ + +
+
+
+

Threads:

+ {% if threads %} + {% for thread in threads %} +
+
+ {{thread.title}} +

{{thread.get_comments_count}}{% if thread.get_comments_count > 1 %} replies{% else %} reply{% endif %}

+
+ +
+
+ {% endfor %} + {% else %} + No discussion threads are there yet. Create one to start discussing. + {% endif %} +
+
+{% endblock content %} \ No newline at end of file diff --git a/yaksh/templates/yaksh/course_modules.html b/yaksh/templates/yaksh/course_modules.html index dd7b68d..b808562 100644 --- a/yaksh/templates/yaksh/course_modules.html +++ b/yaksh/templates/yaksh/course_modules.html @@ -7,6 +7,7 @@
{{ course.name }} + Discussion Forum
{% if course.view_grade %} diff --git a/yaksh/templates/yaksh/thread_comments.html b/yaksh/templates/yaksh/thread_comments.html new file mode 100644 index 0000000..245c363 --- /dev/null +++ b/yaksh/templates/yaksh/thread_comments.html @@ -0,0 +1,46 @@ +{% extends "user.html" %} + +{% block title %} + {{thread.title}} +{% endblock title %} + +{% block content %} +
+ Back to Threads +
+
+ {{thread.title}} +
+ {{thread.creator.username}} {{thread.created_at}} +
+
+

{{thread.description}}

+
+
+
+
+ {% if comments %} +
Comments:
+ {% for comment in comments %} +
+

{{comment.body}}

+ by: {{comment.user.username}} . {{comment.created_at}} +
+
+ {% endfor %} + {% else %} + No comments on this thread. + {% endif %} +
+
+
+
+
+ {% csrf_token %} + +
+ +
+
+
+{% endblock content %} \ No newline at end of file diff --git a/yaksh/urls.py b/yaksh/urls.py index bdc3330..47cfad4 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -59,6 +59,8 @@ urlpatterns = [ views.get_next_unit, name='next_unit'), url(r'^course_modules/(?P\d+)/$', views.course_modules, name='course_modules'), + url(r'^forum/(?P\d+)/$', views.course_forum, name='course_forum'), + url(r'^forum/(?P\d+)/thread/(?P[0-9a-f-]+)/', views.thread_comments, name='thread_comments'), url(r'^manage/$', views.prof_manage, name='manage'), url(r'^manage/addquestion/$', views.add_question, name="add_question"), url(r'^manage/addquestion/(?P\d+)/$', views.add_question, diff --git a/yaksh/views.py b/yaksh/views.py index 9efcbe9..9350f0a 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -1,6 +1,6 @@ import os import csv -from django.http import HttpResponse, JsonResponse +from django.http import HttpResponse, JsonResponse, HttpResponseRedirect from django.contrib.auth import login, logout, authenticate from django.shortcuts import render, get_object_or_404, redirect from django.template import Context, Template @@ -37,7 +37,7 @@ from yaksh.models import ( QuestionPaper, QuestionSet, Quiz, Question, StandardTestCase, StdIOBasedTestCase, StringTestCase, TestCase, User, get_model_class, FIXTURES_DIR_PATH, MOD_GROUP_NAME, Lesson, LessonFile, - LearningUnit, LearningModule, CourseStatus, question_types + LearningUnit, LearningModule, CourseStatus, question_types, Thread, Comment ) from yaksh.forms import ( UserRegisterForm, UserLoginForm, QuizForm, QuestionForm, @@ -3191,3 +3191,44 @@ def download_course_progress(request, course_id): for student in stud_details: writer.writerow(student) return response + + +def course_forum(request, course_id): + user = request.user + course = get_object_or_404(Course, id=course_id) + threads = course.thread.all().order_by('modified_at') + if request.method == "POST": + title = request.POST['title'] + description = request.POST['description'] + if title and description: + new_thread = Thread.objects.create(title=title, + description=description, + creator=user, course=course) + new_thread.save() + return render(request, 'yaksh/thread_comments.html', { + 'thread': new_thread, + 'course': course, + 'user': user, + }) + return render(request, 'yaksh/course_forum.html', { + 'user': user, + 'course': course, + 'threads': threads + }) + + +def thread_comments(request, course_id, uuid): + thread = get_object_or_404(Thread, uid=uuid) + comments = thread.comment.filter(active=True) + if request.method == "POST": + comment = request.POST.get('comment') + if comment is not None: + new_comment = Comment.objects.create(thread=thread, + body=comment, + user=request.user) + new_comment.save() + return HttpResponseRedirect(request.path_info) + return render(request, 'yaksh/thread_comments.html', { + 'thread': thread, + 'comments': comments + }) \ No newline at end of file -- cgit