Commit 5945a147106e1db508194aff22f249ffafef5eb8
1 parent
f5e851c2
Exists in
master
and in
5 other branches
Adding exam crud log functions [Issue: #249]
Showing
3 changed files
with
126 additions
and
8 deletions
Show diff stats
exam/templates/exam/create.html
exam/templates/exam/multiple_choice_question.html
@@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
31 | <!-- new alternative button --> | 31 | <!-- new alternative button --> |
32 | <div class="form-group"> | 32 | <div class="form-group"> |
33 | <div class="col-md-12 col-md-offset-2"> | 33 | <div class="col-md-12 col-md-offset-2"> |
34 | - <button type="button" class="btn btn-primary" id="newAlternative">{% trans 'New Alternative' %]</button> | 34 | + <button type="button" class="btn btn-primary" id="newAlternative">{% trans 'New Alternative' %}</button> |
35 | </div> | 35 | </div> |
36 | </div> | 36 | </div> |
37 | <div class="form-group"> | 37 | <div class="form-group"> |
exam/views.py
@@ -9,15 +9,21 @@ from django.utils.translation import ugettext_lazy as _ | @@ -9,15 +9,21 @@ from django.utils.translation import ugettext_lazy as _ | ||
9 | from rolepermissions.verifications import has_role | 9 | from rolepermissions.verifications import has_role |
10 | from rolepermissions.verifications import has_object_permission | 10 | from rolepermissions.verifications import has_object_permission |
11 | from django.db.models import Q | 11 | from django.db.models import Q |
12 | +from datetime import datetime | ||
12 | # from django.views.generic.edit import FormMixin | 13 | # from django.views.generic.edit import FormMixin |
13 | 14 | ||
14 | from .forms import ExamForm | 15 | from .forms import ExamForm |
15 | from .models import Exam, Answer, AnswersStudent | 16 | from .models import Exam, Answer, AnswersStudent |
16 | -from core.mixins import NotificationMixin | 17 | +from core.mixins import LogMixin, NotificationMixin |
18 | +from core.models import Log | ||
17 | from users.models import User | 19 | from users.models import User |
18 | from courses.models import Course, Topic | 20 | from courses.models import Course, Topic |
19 | 21 | ||
20 | -class ViewExam(LoginRequiredMixin,generic.DetailView): | 22 | +class ViewExam(LoginRequiredMixin, LogMixin, generic.DetailView): |
23 | + log_component = 'exam' | ||
24 | + log_resource = 'exam' | ||
25 | + log_action = 'viewed' | ||
26 | + log_context = {} | ||
21 | 27 | ||
22 | model = Exam | 28 | model = Exam |
23 | context_object_name = 'exam' | 29 | context_object_name = 'exam' |
@@ -40,11 +46,34 @@ class ViewExam(LoginRequiredMixin,generic.DetailView): | @@ -40,11 +46,34 @@ class ViewExam(LoginRequiredMixin,generic.DetailView): | ||
40 | context['status'] = False | 46 | context['status'] = False |
41 | else: | 47 | else: |
42 | context['status'] = answered[0].status | 48 | context['status'] = answered[0].status |
49 | + | ||
50 | + self.log_context['exam_id'] = exam.id | ||
51 | + self.log_context['topic_id'] = exam.topic.id | ||
52 | + self.log_context['topic_name'] = exam.topic.name | ||
53 | + self.log_context['topic_slug'] = exam.topic.slug | ||
54 | + self.log_context['subject_id'] = exam.topic.subject.id | ||
55 | + self.log_context['subject_name'] = exam.topic.subject.name | ||
56 | + self.log_context['subject_slug'] = exam.topic.subject.slug | ||
57 | + self.log_context['course_id'] = exam.topic.subject.course.id | ||
58 | + self.log_context['course_name'] = exam.topic.subject.course.name | ||
59 | + self.log_context['course_slug'] = exam.topic.subject.course.slug | ||
60 | + self.log_context['course_category_id'] = exam.topic.subject.course.category.id | ||
61 | + self.log_context['course_category_name'] = exam.topic.subject.course.category.name | ||
62 | + | ||
63 | + super(ViewExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
64 | + | ||
65 | + self.request.session['time_spent'] = str(datetime.now()) | ||
66 | + self.request.session['log_id'] = Log.objects.latest('id').id | ||
67 | + | ||
43 | return context | 68 | return context |
44 | 69 | ||
45 | 70 | ||
46 | 71 | ||
47 | -class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.CreateView): | 72 | +class CreateExam(LoginRequiredMixin,HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView): |
73 | + log_component = 'exam' | ||
74 | + log_resource = 'exam' | ||
75 | + log_action = 'create' | ||
76 | + log_context = {} | ||
48 | 77 | ||
49 | allowed_roles = ['professor', 'system_admin'] | 78 | allowed_roles = ['professor', 'system_admin'] |
50 | login_url = reverse_lazy("core:home") | 79 | login_url = reverse_lazy("core:home") |
@@ -83,6 +112,21 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.Crea | @@ -83,6 +112,21 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.Crea | ||
83 | answer = Answer(answer=self.request.POST[key],order=key,exam=self.object) | 112 | answer = Answer(answer=self.request.POST[key],order=key,exam=self.object) |
84 | answer.save() | 113 | answer.save() |
85 | 114 | ||
115 | + self.log_context['exam_id'] = self.object.id | ||
116 | + self.log_context['topic_id'] = self.object.topic.id | ||
117 | + self.log_context['topic_name'] = self.object.topic.name | ||
118 | + self.log_context['topic_slug'] = self.object.topic.slug | ||
119 | + self.log_context['subject_id'] = self.object.topic.subject.id | ||
120 | + self.log_context['subject_name'] = self.object.topic.subject.name | ||
121 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | ||
122 | + self.log_context['course_id'] = self.object.topic.subject.course.id | ||
123 | + self.log_context['course_name'] = self.object.topic.subject.course.name | ||
124 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | ||
125 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | ||
126 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | ||
127 | + | ||
128 | + super(CreateExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
129 | + | ||
86 | return self.render_to_response(self.get_context_data(form = form), status = 200) | 130 | return self.render_to_response(self.get_context_data(form = form), status = 200) |
87 | 131 | ||
88 | def get_context_data(self, **kwargs): | 132 | def get_context_data(self, **kwargs): |
@@ -93,7 +137,11 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.Crea | @@ -93,7 +137,11 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.Crea | ||
93 | context['subjects'] = topic.subject.course.subjects.all() | 137 | context['subjects'] = topic.subject.course.subjects.all() |
94 | return context | 138 | return context |
95 | 139 | ||
96 | -class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | 140 | +class UpdateExam(LoginRequiredMixin,HasRoleMixin, LogMixin, generic.UpdateView): |
141 | + log_component = 'exam' | ||
142 | + log_resource = 'exam' | ||
143 | + log_action = 'update' | ||
144 | + log_context = {} | ||
97 | 145 | ||
98 | allowed_roles = ['professor', 'system_admin'] | 146 | allowed_roles = ['professor', 'system_admin'] |
99 | login_url = reverse_lazy("core:home") | 147 | login_url = reverse_lazy("core:home") |
@@ -139,6 +187,21 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | @@ -139,6 +187,21 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | ||
139 | answer = Answer(answer=self.request.POST[key],order=key,exam=exam) | 187 | answer = Answer(answer=self.request.POST[key],order=key,exam=exam) |
140 | answer.save() | 188 | answer.save() |
141 | 189 | ||
190 | + self.log_context['exam_id'] = self.object.id | ||
191 | + self.log_context['topic_id'] = self.object.topic.id | ||
192 | + self.log_context['topic_name'] = self.object.topic.name | ||
193 | + self.log_context['topic_slug'] = self.object.topic.slug | ||
194 | + self.log_context['subject_id'] = self.object.topic.subject.id | ||
195 | + self.log_context['subject_name'] = self.object.topic.subject.name | ||
196 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | ||
197 | + self.log_context['course_id'] = self.object.topic.subject.course.id | ||
198 | + self.log_context['course_name'] = self.object.topic.subject.course.name | ||
199 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | ||
200 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | ||
201 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | ||
202 | + | ||
203 | + super(UpdateExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
204 | + | ||
142 | return super(UpdateExam, self).form_valid(form) | 205 | return super(UpdateExam, self).form_valid(form) |
143 | 206 | ||
144 | def get_context_data(self, **kwargs): | 207 | def get_context_data(self, **kwargs): |
@@ -158,7 +221,11 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | @@ -158,7 +221,11 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | ||
158 | 221 | ||
159 | return context | 222 | return context |
160 | 223 | ||
161 | -class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | 224 | +class DeleteExam(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView): |
225 | + log_component = 'exam' | ||
226 | + log_resource = 'exam' | ||
227 | + log_action = 'delete' | ||
228 | + log_context = {} | ||
162 | 229 | ||
163 | allowed_roles = ['professor', 'system_admin'] | 230 | allowed_roles = ['professor', 'system_admin'] |
164 | login_url = reverse_lazy("core:home") | 231 | login_url = reverse_lazy("core:home") |
@@ -184,12 +251,31 @@ class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | @@ -184,12 +251,31 @@ class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | ||
184 | return context | 251 | return context |
185 | 252 | ||
186 | def get_success_url(self): | 253 | def get_success_url(self): |
254 | + self.log_context['exam_id'] = self.object.id | ||
255 | + self.log_context['topic_id'] = self.object.topic.id | ||
256 | + self.log_context['topic_name'] = self.object.topic.name | ||
257 | + self.log_context['topic_slug'] = self.object.topic.slug | ||
258 | + self.log_context['subject_id'] = self.object.topic.subject.id | ||
259 | + self.log_context['subject_name'] = self.object.topic.subject.name | ||
260 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | ||
261 | + self.log_context['course_id'] = self.object.topic.subject.course.id | ||
262 | + self.log_context['course_name'] = self.object.topic.subject.course.name | ||
263 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | ||
264 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | ||
265 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | ||
266 | + | ||
267 | + super(DeleteExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
268 | + | ||
187 | return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug}) | 269 | return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug}) |
188 | 270 | ||
189 | class AnswerExam(generic.TemplateView): | 271 | class AnswerExam(generic.TemplateView): |
190 | template_name = 'exam/answer.html' | 272 | template_name = 'exam/answer.html' |
191 | 273 | ||
192 | -class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | 274 | +class AnswerStudentExam(LoginRequiredMixin, LogMixin, generic.CreateView): |
275 | + log_component = 'exam' | ||
276 | + log_resource = 'exam' | ||
277 | + log_action = 'answer' | ||
278 | + log_context = {} | ||
193 | 279 | ||
194 | model = AnswersStudent | 280 | model = AnswersStudent |
195 | fields = ['status'] | 281 | fields = ['status'] |
@@ -209,6 +295,36 @@ class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | @@ -209,6 +295,36 @@ class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | ||
209 | if(key != 'csrfmiddlewaretoken'): | 295 | if(key != 'csrfmiddlewaretoken'): |
210 | answers.answer.add(exam.answers.all().filter(order=key)[0]) | 296 | answers.answer.add(exam.answers.all().filter(order=key)[0]) |
211 | 297 | ||
298 | + self.log_context['exam_id'] = exam.id | ||
299 | + self.log_context['topic_id'] = exam.topic.id | ||
300 | + self.log_context['topic_name'] = exam.topic.name | ||
301 | + self.log_context['topic_slug'] = exam.topic.slug | ||
302 | + self.log_context['subject_id'] = exam.topic.subject.id | ||
303 | + self.log_context['subject_name'] = exam.topic.subject.name | ||
304 | + self.log_context['subject_slug'] = exam.topic.subject.slug | ||
305 | + self.log_context['course_id'] = exam.topic.subject.course.id | ||
306 | + self.log_context['course_name'] = exam.topic.subject.course.name | ||
307 | + self.log_context['course_slug'] = exam.topic.subject.course.slug | ||
308 | + self.log_context['course_category_id'] = exam.topic.subject.course.category.id | ||
309 | + self.log_context['course_category_name'] = exam.topic.subject.course.category.name | ||
310 | + | ||
311 | + date_time_click = datetime.strptime(self.request.session.get('time_spent'), "%Y-%m-%d %H:%M:%S.%f") | ||
312 | + _now = datetime.now() | ||
313 | + | ||
314 | + time_spent = _now - date_time_click | ||
315 | + | ||
316 | + secs = time_spent.total_seconds() | ||
317 | + hours = int(secs / 3600) | ||
318 | + minutes = int(secs / 60) % 60 | ||
319 | + secs = secs % 60 | ||
320 | + | ||
321 | + self.log_context['time_spent'] = {} | ||
322 | + self.log_context['time_spent']['hours'] = hours | ||
323 | + self.log_context['time_spent']['minutes'] = minutes | ||
324 | + self.log_context['time_spent']['seconds'] = secs | ||
325 | + | ||
326 | + super(AnswerStudentExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
327 | + | ||
212 | return self.render_to_response(self.get_context_data(form = form), status = 200) | 328 | return self.render_to_response(self.get_context_data(form = form), status = 200) |
213 | 329 | ||
214 | def get_context_data(self, **kwargs): | 330 | def get_context_data(self, **kwargs): |
@@ -230,6 +346,8 @@ class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | @@ -230,6 +346,8 @@ class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | ||
230 | context['answers'] = answers | 346 | context['answers'] = answers |
231 | context['keys'] = keys | 347 | context['keys'] = keys |
232 | 348 | ||
349 | + self.request.session['time_spent'] = str(datetime.now()) | ||
350 | + | ||
233 | return context | 351 | return context |
234 | 352 | ||
235 | class MultipleChoiceQuestion(generic.TemplateView): | 353 | class MultipleChoiceQuestion(generic.TemplateView): |