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 @@
{% 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.description}}
+
+
+
+
+ {% if comments %}
+
+ {% for comment in comments %}
+
+
{{comment.body}}
+
by: {{comment.user.username}} . {{comment.created_at}}
+
+
+ {% endfor %}
+ {% else %}
+ No comments on this thread.
+ {% endif %}
+
+
+
+
+
+
+{% 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