From d9793c01304498d7f59820cf2ab2d7a5483851f8 Mon Sep 17 00:00:00 2001
From: prathamesh
Date: Wed, 2 Mar 2016 15:48:39 +0530
Subject: Course module implemented
Moderator can now create courses. Under his courses he can create quizzes.
Students can enroll for the course. Moderator can approve or reject
enrollment request of the student.
Student can view quizzes only for the enrolled course.
---
yaksh/forms.py | 17 +++-
yaksh/models.py | 67 ++++++++++++++
yaksh/static/yaksh/css/course.css | 18 ++++
yaksh/static/yaksh/css/question_quiz.css | 3 +
yaksh/templates/manage.html | 6 +-
yaksh/templates/yaksh/add_course.html | 21 +++++
yaksh/templates/yaksh/add_quiz.html | 2 +-
yaksh/templates/yaksh/course_detail.html | 59 ++++++++++++
yaksh/templates/yaksh/courses.html | 39 ++++++++
yaksh/templates/yaksh/quizzes_user.html | 153 +++++++++++++++++++------------
yaksh/urls.py | 12 +++
yaksh/views.py | 121 ++++++++++++++++++++++--
12 files changed, 441 insertions(+), 77 deletions(-)
create mode 100644 yaksh/static/yaksh/css/course.css
create mode 100644 yaksh/templates/yaksh/add_course.html
create mode 100644 yaksh/templates/yaksh/course_detail.html
create mode 100644 yaksh/templates/yaksh/courses.html
(limited to 'yaksh')
diff --git a/yaksh/forms.py b/yaksh/forms.py
index de40419..1af02f7 100644
--- a/yaksh/forms.py
+++ b/yaksh/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from yaksh.models import Profile, Quiz, Question, TestCase
+from yaksh.models import Profile, Quiz, Question, TestCase, Course
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
@@ -132,12 +132,15 @@ class QuizForm(forms.Form):
It has the related fields and functions required."""
def __init__(self, *args, **kwargs):
+ user = kwargs.pop('user')
super(QuizForm, self).__init__(*args, **kwargs)
quizzes = [('', 'Select a prerequisite quiz')]
- quizzes = quizzes + \
- list(Quiz.objects.values_list('id', 'description'))
+ quizzes += list(Quiz.objects.filter(
+ course__creator=user).values_list('id', 'description'))
self.fields['prerequisite'] = forms.CharField(required=False,
widget=forms.Select(choices=quizzes))
+ self.fields['course'] = forms.ModelChoiceField(
+ queryset=Course.objects.filter(creator=user))
start_date = forms.DateField(initial=datetime.date.today(), required=False)
start_time = forms.TimeField(initial=datetime.datetime.now().time(), required=False)
@@ -156,6 +159,7 @@ class QuizForm(forms.Form):
help_text='Will be in days')
def save(self):
+ course = self.cleaned_data["course"]
start_date = self.cleaned_data["start_date"]
start_time = self.cleaned_data["start_time"]
end_date = self.cleaned_data["end_date"]
@@ -169,6 +173,7 @@ class QuizForm(forms.Form):
attempts_allowed = self.cleaned_data["attempts_allowed"]
time_between_attempts = self.cleaned_data["time_between_attempts"]
new_quiz = Quiz()
+ new_quiz.course = course
new_quiz.start_date_time = datetime.datetime.combine(start_date,
start_time)
new_quiz.end_date_time = datetime.datetime.combine(end_date,
@@ -265,3 +270,9 @@ class QuestionFilterForm(forms.Form):
TestCaseFormSet = inlineformset_factory(Question, TestCase,\
can_order=False, can_delete=False, extra=1)
+
+
+class CourseForm(forms.ModelForm):
+ class Meta:
+ model = Course
+ fields = ['name', 'active', 'enrollment']
diff --git a/yaksh/models.py b/yaksh/models.py
index 8415930..d6fe972 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -40,6 +40,12 @@ question_types = (
("code", "Code"),
("upload", "Assignment Upload"),
)
+
+enrollment_methods = (
+ ("default", "Enroll Request"),
+ ("open", "Open Course"),
+ )
+
attempts = [(i, i) for i in range(1, 6)]
attempts.append((-1, 'Infinite'))
days_between_attempts = ((j, j) for j in range(401))
@@ -54,6 +60,65 @@ def get_assignment_dir(instance, filename):
return '%s/%s' % (instance.user.roll_number, instance.assignmentQuestion.id)
+###############################################################################
+class Course(models.Model):
+ name = models.CharField(max_length=128)
+ enrollment = models.CharField(max_length=32, choices=enrollment_methods)
+ active = models.BooleanField(default=True)
+ creator = models.ForeignKey(User, related_name='creator')
+ students = models.ManyToManyField(User, related_name='students')
+ requests = models.ManyToManyField(User, related_name='requests')
+ rejected = models.ManyToManyField(User, related_name='rejected')
+ created_on = models.DateTimeField(default=datetime.datetime.now())
+
+ def request(self, *users):
+ self.requests.add(*users)
+
+ def get_requests(self):
+ return self.requests.all()
+
+ def reject(self, was_enrolled=False, *users):
+ self.rejected.add(*users)
+ if not was_enrolled:
+ self.requests.remove(*users)
+ else:
+ self.students.remove(*users)
+
+ def get_rejected(self):
+ return self.rejected.all()
+
+ def enroll(self, was_rejected=False, *users):
+ self.students.add(*users)
+ if not was_rejected:
+ self.requests.remove(*users)
+ else:
+ self.rejected.remove(*users)
+
+ def get_enrolled(self):
+ return self.students.all()
+
+ def is_enrolled(self, user_id):
+ return self.students.filter(id=user_id).exists()
+
+ def is_creator(self, user):
+ return self.creator == user
+
+ def get_quizzes(self):
+ return self.quiz_set.all()
+
+ def activate(self):
+ self.active = True
+
+ def deactivate(self):
+ self.active = False
+
+ def is_self_enroll(self):
+ return True if self.enrollment == 'open' else False
+
+ def __unicode__(self):
+ return self.name
+
+
###############################################################################
class Question(models.Model):
"""Question for a quiz."""
@@ -166,6 +231,8 @@ class Quiz(models.Model):
as the "examination" event.
"""
+ course = models.ForeignKey(Course)
+
# The start date of the quiz.
start_date_time = models.DateTimeField("Start Date and Time of the quiz",
default=datetime.datetime.now(),
diff --git a/yaksh/static/yaksh/css/course.css b/yaksh/static/yaksh/css/course.css
new file mode 100644
index 0000000..580a95c
--- /dev/null
+++ b/yaksh/static/yaksh/css/course.css
@@ -0,0 +1,18 @@
+.show-grid [class*="span"] {
+ background: none repeat scroll 0% 0% #EEE;
+ text-align: center;
+ border-radius: 10px;
+ min-height: 30px;
+ line-height: 30px;
+ padding: 5px;
+}
+
+.well{
+ padding: 4px;
+}
+
+.wrap{
+ border: 1px solid #333;
+ padding: 5px;
+ background: none repeat scroll 0% 0% #E0DADA;
+}
diff --git a/yaksh/static/yaksh/css/question_quiz.css b/yaksh/static/yaksh/css/question_quiz.css
index ee249d4..26dc42b 100644
--- a/yaksh/static/yaksh/css/question_quiz.css
+++ b/yaksh/static/yaksh/css/question_quiz.css
@@ -22,3 +22,6 @@ table th, table td
height : 30px;
width : 100px;
}
+input, textarea, select, .uneditable-input {
+ height: 30px;
+}
diff --git a/yaksh/templates/manage.html b/yaksh/templates/manage.html
index ca2ac65..11e2187 100644
--- a/yaksh/templates/manage.html
+++ b/yaksh/templates/manage.html
@@ -27,9 +27,9 @@
Online Test
Course
+ {{ course.name }} + +You have not passed the prerequisite & hence you cannot take the quiz.
- {% endif %} -Quiz | -Pre requisite quiz | - {% for paper in quizzes %} -|||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- {{ paper.quiz.description }} - |
- {% else %}
-
- {{ paper.quiz.description }} Expired - |
+
+
Quiz | +Pre requisite quiz | + {% for paper in quizzes %} + {% if paper.quiz.course_id == course.id %} +|
---|---|---|
+ {{ paper.quiz.description }} + |
+ {% else %}
+
+ {{ paper.quiz.description }} Expired + |
+ {% endif %}
+ + {% if paper.quiz.prerequisite %} + You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }} + {% else %} + No pre requisites for {{ paper.quiz.description }} + {% endif %} + | +
Quiz | +Result | +Marks Obtained | +Total Marks | +Percentage | + {% for paper in quizzes_taken %} +
---|---|---|---|---|
- {% if paper.quiz.prerequisite %} - You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }} + {{ paper.question_paper.quiz.description }} + | +
+ {% if paper.passed %}
+ Pass {% else %} - No pre requisites for {{ paper.quiz.description }} +Fail {% endif %} |
+ + {{ paper.marks_obtained }} + | ++ {{ paper.question_paper.total_marks }} + | ++ {{ paper.percent }} + |
Quiz | -Result | -Marks Obtained | -Total Marks | -Percentage | - {% for paper in quizzes_taken %} -
---|---|---|---|---|
- {{ paper.question_paper.quiz.description }} - | -
- {% if paper.passed %}
- Pass - {% else %} -Fail - {% endif %} - |
- - {{ paper.marks_obtained }} - | -- {{ paper.question_paper.total_marks }} - | -- {{ paper.percent }} - | -
You have not taken any quiz yet !!
- {% endif %} +{% else %} +You have not taken any quiz yet !!
+{% endif %} {% endblock %} diff --git a/yaksh/urls.py b/yaksh/urls.py index e6c2e15..ad0a925 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -19,6 +19,8 @@ urlpatterns = patterns('yaksh.views', 'check'), url(r'^intro/$', 'start'), url(r'^(?P