Commit 9313f27f1e6b9418c8781d446f0bf6e644c6dee6
1 parent
2ceb0949
Exists in
master
and in
5 other branches
modificações no app exam #171
Showing
13 changed files
with
185 additions
and
139 deletions
Show diff stats
courses/urls.py
exam/admin.py
1 | 1 | from django.contrib import admin |
2 | 2 | |
3 | -# Register your models here. | |
3 | +from .models import Exam, Answer | |
4 | + | |
5 | +class ExamAdmin(admin.ModelAdmin): | |
6 | + list_display = ['name', 'slug','begin_date','limit_date'] | |
7 | + search_fields = ['name','slug'] | |
8 | + | |
9 | +class AnswerAdmin(admin.ModelAdmin): | |
10 | + list_display = ['answer','order'] | |
11 | + search_fields = ['answer'] | |
12 | + | |
13 | +admin.site.register(Exam, ExamAdmin) | |
14 | +admin.site.register(Answer, AnswerAdmin) | ... | ... |
exam/forms.py
1 | +from django.utils.translation import ugettext_lazy as _ | |
1 | 2 | from django import forms |
2 | 3 | from .models import Exam |
3 | 4 | |
4 | 5 | class ExamForm(forms.ModelForm): |
5 | 6 | def clean_end_date(self): |
6 | - beginDate = self.data['beginDate'] | |
7 | - endDate = self.data['endDate'] | |
7 | + begin_date = self.data['begin_date'] | |
8 | + limit_date = self.data['limit_date'] | |
8 | 9 | |
9 | - if beginDate and endDate and endDate < beginDate: | |
10 | + if begin_date and limit_date and limit_date < begin_date: | |
10 | 11 | raise forms.ValidationError(_('The end date may not be before the start date.')) |
11 | 12 | return endDate |
12 | 13 | |
13 | - def clean_begin_date(self): | |
14 | - endDate = self.data['endDate'] | |
15 | - beginDate = self.data['beginDate'] | |
16 | - | |
17 | - if enDate and benginDate and beginDate <= endDate: | |
18 | - raise forms.ValidationError(_('The exam start date must be after the end of registration.')) | |
19 | - return beginDate | |
20 | - | |
21 | - def clean_end_date(self): | |
22 | - beginDate = self.data['beginDate'] | |
23 | - endDate = self.data['endDate'] | |
24 | - | |
25 | - if beginDate and endDate and endDate < beginDate: | |
26 | - raise forms.ValidationError(_('The finish date may not be before the start date.')) | |
27 | - return end_date | |
28 | - | |
29 | - | |
30 | 14 | |
31 | 15 | class Meta: |
32 | 16 | model = Exam |
33 | - fields = ['name','beginDate','endDate'] | |
17 | + fields = ['name','begin_date','limit_date'] | |
34 | 18 | |
35 | 19 | widgets = { |
36 | 20 | 'name': forms.TextInput(attrs={'placeholder': 'Exam?'}), |
37 | - 'beginDate': forms.DateTimeInput(attrs={'placeholder': 'Start date to resolve the exam'}), | |
38 | - 'endDate': forms.DateTimeInput(attrs={'placeholder': 'Finish date permited to resolve the exam'}), | |
21 | + 'begin_date': forms.DateTimeInput(attrs={'placeholder': _('Start date to resolve the exam')}), | |
22 | + 'limit_date': forms.DateTimeInput(attrs={'placeholder': _('Finish date permited to resolve the exam')}), | |
39 | 23 | } | ... | ... |
exam/models.py
... | ... | @@ -5,23 +5,19 @@ from users.models import User |
5 | 5 | from core.models import Resource |
6 | 6 | from courses.models import Activity |
7 | 7 | |
8 | - | |
9 | - | |
10 | -class Exam(models.Model): | |
11 | - name = models.CharField(_('Name'), max_length = 100) | |
12 | - beginDate = models.DateTimeField(_('Start Date'), auto_now_add = True) | |
13 | - endDate = models.DateTimeField(_('Date of last update'), auto_now=True) | |
8 | +class Exam(Activity): | |
9 | + begin_date = models.DateField(_('Begin of Course Date')) | |
14 | 10 | |
15 | 11 | class Meta: |
16 | - #ordering = ('create_date','name') | |
17 | 12 | verbose_name = _('Exam') |
18 | 13 | verbose_name_plural = _('Exams') |
19 | 14 | |
20 | 15 | def __str__(self): |
21 | 16 | return str(self.name) + str("/") + str(self.topic) |
22 | 17 | |
18 | + | |
23 | 19 | class Answer(models.Model): |
24 | - answer = models.CharField(_("Answer"), max_length = 200) | |
20 | + answer = models.CharField(_("Answer"), max_length = 300) | |
25 | 21 | order = models.PositiveSmallIntegerField(_("Order")) |
26 | 22 | exam = models.ForeignKey(Exam, verbose_name = _('Answers'), related_name='answers') |
27 | 23 | ... | ... |
exam/permisissions.py
... | ... | @@ -1,12 +0,0 @@ |
1 | -from rolepermissions.permissions import register_object_checker | |
2 | -from amadeus.roles import SystemAdmin | |
3 | - | |
4 | -@register_object_checker() | |
5 | -def edit_exam(role, user, exam): | |
6 | - if (role == SystemAdmin): | |
7 | - return True | |
8 | - | |
9 | - if (user in exam.topic.subject.professors.all()): | |
10 | - return True | |
11 | - | |
12 | - return False |
... | ... | @@ -0,0 +1,12 @@ |
1 | +from rolepermissions.permissions import register_object_checker | |
2 | +from amadeus.roles import SystemAdmin | |
3 | + | |
4 | +@register_object_checker() | |
5 | +def edit_exam(role, user, exam): | |
6 | + if (role == SystemAdmin): | |
7 | + return True | |
8 | + | |
9 | + if (user in exam.topic.subject.professors.all()): | |
10 | + return True | |
11 | + | |
12 | + return False | ... | ... |
exam/templates/exam/form_exam.html
... | ... | @@ -1,60 +0,0 @@ |
1 | -<div class="panel panel-info"> | |
2 | - <div class="panel-heading"> | |
3 | - <h3 class="panel-title">New Exam</h3> | |
4 | - </div> | |
5 | - <div class="panel-body"> | |
6 | - <form class="form-horizontal"> | |
7 | - | |
8 | - <div class="form-group"> | |
9 | - <label for="examName" class="col-md-2 control-label">Exam Name</label> | |
10 | - | |
11 | - <div class="col-md-10"> | |
12 | - <input type="text" class="form-control" id="examName" placeholder="Exam Name"> | |
13 | - </div> | |
14 | - | |
15 | - | |
16 | - </div> | |
17 | - <div class="form-group"> | |
18 | - <label for="Date" class="col-md-2 control-label">Exam Period</label> | |
19 | - <div class="col-md-5"> | |
20 | - <input type="date" class="form-control" id="beginDate" placeholder="Begin Date"> | |
21 | - | |
22 | - </div> | |
23 | - <div class="col-md-5"> | |
24 | - <input type="date" class="form-control" id="endDate" placeholder="End Date"> | |
25 | - | |
26 | - </div> | |
27 | - </div> | |
28 | - <div class="form-group"> | |
29 | - <label for="deadline" class="col-md-2 control-label">Allow submissions after deadline?</label> | |
30 | - <div class="col-md-10"> | |
31 | - <label> | |
32 | - <input type="checkbox"> | |
33 | - </label> | |
34 | - </div> | |
35 | - </div> | |
36 | - <div class="form-group"> | |
37 | - <label for="questionType" class="col-md-2 control-label">Question Type</label> | |
38 | - <div class="col-md-10"> | |
39 | - <select id="questionType" class="form-control" onchange="showDiv (this)"> | |
40 | - <option selected disabled>Question Type</option> | |
41 | - <option value="0">Multiple Choice</option> | |
42 | - <option value="1">True or False</option> | |
43 | - <option value="2">Gap Filling</option> | |
44 | - <option value="3">Discursive Question</option> | |
45 | - </select> | |
46 | - </div> | |
47 | - </div> | |
48 | - </form> | |
49 | - </div> | |
50 | -</div> | |
51 | - | |
52 | -<script> | |
53 | - function showDiv (elem) { | |
54 | - if (elem.value == 0) { | |
55 | - document.getElementById('multipleChoice').style.display = "block"; | |
56 | - } else if (elem.value == 1) { | |
57 | - document.getElementById('trueOrFalse').style.display = "block"; | |
58 | - } | |
59 | - } | |
60 | -</script> |
exam/urls.py
... | ... | @@ -3,7 +3,8 @@ from django.conf.urls import url |
3 | 3 | from . import views |
4 | 4 | |
5 | 5 | urlpatterns = [ |
6 | - url(r'^create/(?P<slug>[\w\-_]+)/$', views.CreateExam.as_view(), name='create_poll'), | |
7 | - url(r'^update/(?P<slug>[\w\-_]+)/$', views.UpdateExam.as_view(), name='update_poll'), | |
8 | - | |
6 | + url(r'^create/(?P<slug>[\w\-_]+)/$', views.CreateExam.as_view(), name='create_exam'), | |
7 | + url(r'^update/(?P<slug>[\w\-_]+)/$', views.UpdateExam.as_view(), name='update_exam'), | |
8 | + url(r'^view/(?P<slug>[\w\-_]+)/$', views.ViewExam.as_view(), name='view_exam'), | |
9 | + url(r'^delete/(?P<slug>[\w\-_]+)/$', views.DeleteExam.as_view(), name='delete_exam'), | |
9 | 10 | ] | ... | ... |
exam/views.py
... | ... | @@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse_lazy |
8 | 8 | from django.utils.translation import ugettext_lazy as _ |
9 | 9 | from rolepermissions.verifications import has_role |
10 | 10 | from rolepermissions.verifications import has_object_permission |
11 | +from django.db.models import Q | |
11 | 12 | # from django.views.generic.edit import FormMixin |
12 | 13 | |
13 | 14 | from .forms import ExamForm |
... | ... | @@ -16,34 +17,76 @@ from core.mixins import NotificationMixin |
16 | 17 | from users.models import User |
17 | 18 | from courses.models import Course, Topic |
18 | 19 | |
19 | -class CreateExam(LoginRequiredMixin,generic.CreateView): | |
20 | +class ViewExam(LoginRequiredMixin,generic.DetailView): | |
20 | 21 | |
21 | - login_url = reverse_lazy("core:home") | |
22 | - redirect_field_name = 'next' | |
23 | 22 | model = Exam |
24 | - form_class = PollForm | |
25 | 23 | context_object_name = 'exam' |
26 | - template_name = 'exam/form_exam.html' | |
27 | - success_url = reverse_lazy('core:home') | |
24 | + template_name = 'exam/view.html' | |
25 | + | |
26 | + def get_object(self, queryset=None): | |
27 | + return get_object_or_404(Exam, slug = self.kwargs.get('slug')) | |
28 | + | |
29 | + def form_invalid(self, form,**kwargs): | |
30 | + context = super(ViewExam, self).form_invalid(form) | |
31 | + answers = {} | |
32 | + for key in self.request.POST: | |
33 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key!= 'begin_date' and key != 'limit_date' and key != 'all_students' and key != 'students'): | |
34 | + answers[key] = self.request.POST[key] | |
35 | + | |
36 | + keys = sorted(answers) | |
37 | + context.context_data['answers'] = answers | |
38 | + context.context_data['keys'] = keys | |
39 | + return context | |
28 | 40 | |
29 | 41 | def form_valid(self, form): |
30 | - self.object = form.save(commit = False) | |
31 | - topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) | |
32 | - self.object.topic = topic | |
33 | - self.object.save() | |
42 | + exam = self.object | |
43 | + exam = form.save(commit = False) | |
44 | + exam.answers.all().delete() | |
45 | + exam.save() | |
46 | + | |
34 | 47 | |
35 | 48 | for key in self.request.POST: |
36 | - if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'beginDate' and key != 'endDate'): | |
37 | - answer = Answer(answer=self.request.POST[key],order=key,poll=self.object) | |
49 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'begin_date' and key != 'limit_date' and key != 'all_students' and key != 'students'): | |
50 | + answer = Answer(answer=self.request.POST[key],order=key,exam=exam) | |
38 | 51 | answer.save() |
39 | 52 | |
40 | - return super(CreateExam, self).form_valid(form) | |
53 | + return super(ViewExam, self).form_valid(form) | |
54 | + | |
55 | + def get_context_data(self, **kwargs): | |
56 | + context = super(ViewExam, self).get_context_data(**kwargs) | |
57 | + exam = self.object | |
58 | + context['course'] = exam.topic.subject.course | |
59 | + context['subject'] = exam.topic.subject | |
60 | + context['subjects'] = exam.topic.subject.course.subjects.all() | |
61 | + | |
62 | + answers = {} | |
63 | + for answer in exam.answers.all(): | |
64 | + answers[answer.order] = answer.answer | |
65 | + | |
66 | + keys = sorted(answers) | |
67 | + context['answers'] = answers | |
68 | + context['keys'] = keys | |
69 | + | |
70 | + print (context) | |
71 | + return context | |
72 | + | |
73 | + | |
74 | +class CreateExam(LoginRequiredMixin,HasRoleMixin,generic.CreateView): | |
75 | + | |
76 | + allowed_roles = ['professor', 'system_admin'] | |
77 | + login_url = reverse_lazy("core:home") | |
78 | + redirect_field_name = 'next' | |
79 | + model = Exam | |
80 | + form_class = ExamForm | |
81 | + context_object_name = 'exam' | |
82 | + template_name = 'exam/create.html' | |
83 | + success_url = reverse_lazy('core:home') | |
41 | 84 | |
42 | 85 | def form_invalid(self, form,**kwargs): |
43 | 86 | context = super(CreateExam, self).form_invalid(form) |
44 | 87 | answers = {} |
45 | 88 | for key in self.request.POST: |
46 | - if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'beginDate' and key != 'endDate'): | |
89 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'begin_date' and key != 'limit_date' and key != 'all_students' and key != 'students'): | |
47 | 90 | answers[key] = self.request.POST[key] |
48 | 91 | |
49 | 92 | keys = sorted(answers) |
... | ... | @@ -51,47 +94,115 @@ class CreateExam(LoginRequiredMixin,generic.CreateView): |
51 | 94 | context.context_data['keys'] = keys |
52 | 95 | return context |
53 | 96 | |
54 | -class UpdateExam(LoginRequiredMixin,generic.UpdateView): | |
97 | + def form_valid(self, form): | |
98 | + self.object = form.save(commit = False) | |
99 | + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) | |
100 | + self.object.topic = topic | |
101 | + self.object.save() | |
55 | 102 | |
103 | + for key in self.request.POST: | |
104 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'begin_date' and key != 'limit_date' and key != 'all_students' and key != 'students'): | |
105 | + answer = Answer(answer=self.request.POST[key],order=key,exam=self.object) | |
106 | + answer.save() | |
107 | + | |
108 | + return super(CreatePoll, self).form_valid(form) | |
109 | + | |
110 | + def get_context_data(self, **kwargs): | |
111 | + context = super(CreateExam, self).get_context_data(**kwargs) | |
112 | + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) | |
113 | + context['course'] = topic.subject.course | |
114 | + context['subject'] = topic.subject | |
115 | + context['subjects'] = topic.subject.course.subjects.all() | |
116 | + return context | |
117 | + | |
118 | +class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | |
119 | + | |
120 | + allowed_roles = ['professor', 'system_admin'] | |
56 | 121 | login_url = reverse_lazy("core:home") |
57 | 122 | redirect_field_name = 'next' |
58 | 123 | model = Exam |
59 | 124 | form_class = ExamForm |
60 | 125 | context_object_name = 'exam' |
61 | - template_name = 'poll/form_exam.html' | |
126 | + template_name = 'exam/update.html' | |
62 | 127 | success_url = reverse_lazy('core:home') |
63 | 128 | |
64 | 129 | def dispatch(self, *args, **kwargs): |
65 | - poll = get_object_or_404(Poll, slug = self.kwargs.get('slug')) | |
66 | - | |
130 | + exam = get_object_or_404(Exam, slug = self.kwargs.get('slug')) | |
67 | 131 | if(not has_object_permission('edit_exam', self.request.user, exam)): |
68 | 132 | return self.handle_no_permission() |
69 | - return super(UpdateExam, self).dispatch(*args, **kwargs) | |
133 | + return super(UpdatePoll, self).dispatch(*args, **kwargs) | |
70 | 134 | |
71 | 135 | def get_object(self, queryset=None): |
72 | - return get_object_or_404(Poll, slug = self.kwargs.get('slug')) | |
136 | + return get_object_or_404(Exam, slug = self.kwargs.get('slug')) | |
137 | + | |
138 | + def form_invalid(self, form,**kwargs): | |
139 | + context = super(UpdateExam, self).form_invalid(form) | |
140 | + answers = {} | |
141 | + for key in self.request.POST: | |
142 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'begin_date' and key != 'limit_date' and key != 'all_students' and key != 'students'): | |
143 | + answers[key] = self.request.POST[key] | |
144 | + | |
145 | + keys = sorted(answers) | |
146 | + context.context_data['answers'] = answers | |
147 | + context.context_data['keys'] = keys | |
148 | + return context | |
73 | 149 | |
74 | 150 | def form_valid(self, form): |
75 | - poll = self.object | |
76 | - poll = form.save(commit = False) | |
77 | - poll.answers.all().delete() | |
78 | - poll.save() | |
151 | + exam = self.object | |
152 | + exam = form.save(commit = False) | |
153 | + exam.answers.all().delete() | |
154 | + exam.save() | |
155 | + | |
79 | 156 | |
80 | 157 | for key in self.request.POST: |
81 | - if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'beginDate' and key != 'endDate'): | |
158 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'begin_date' and key != 'limit_date' and key != 'all_students' and key != 'students'): | |
82 | 159 | answer = Answer(answer=self.request.POST[key],order=key,exam=exam) |
83 | 160 | answer.save() |
84 | 161 | |
85 | 162 | return super(UpdateExam, self).form_valid(form) |
86 | 163 | |
87 | - def form_invalid(self, form,**kwargs): | |
88 | - context = super(UpdateExam, self).form_invalid(form) | |
164 | + def get_context_data(self, **kwargs): | |
165 | + context = super(UpdateExam, self).get_context_data(**kwargs) | |
166 | + exam = self.object | |
167 | + context['course'] = exam.topic.subject.course | |
168 | + context['subject'] = exam.topic.subject | |
169 | + context['subjects'] = exam.topic.subject.course.subjects.all() | |
170 | + | |
89 | 171 | answers = {} |
90 | - for key in self.request.POST: | |
91 | - if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'beginDate' and key != 'endDate'): | |
92 | - answers[key] = self.request.POST[key] | |
172 | + for answer in exam.answers.all(): | |
173 | + # print (key.answer) | |
174 | + answers[answer.order] = answer.answer | |
93 | 175 | |
94 | 176 | keys = sorted(answers) |
95 | - context.context_data['answers'] = answers | |
96 | - context.context_data['keys'] = keys | |
177 | + context['answers'] = answers | |
178 | + context['keys'] = keys | |
179 | + | |
180 | + return context | |
181 | + | |
182 | +class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | |
183 | + | |
184 | + allowed_roles = ['professor', 'system_admin'] | |
185 | + login_url = reverse_lazy("core:home") | |
186 | + redirect_field_name = 'next' | |
187 | + model = Exam | |
188 | + template_name = 'exam/remove.html' | |
189 | + | |
190 | + def dispatch(self, *args, **kwargs): | |
191 | + exam = get_object_or_404(Exam, slug = self.kwargs.get('slug')) | |
192 | + if(not has_object_permission('delete_exam', self.request.user, exam)): | |
193 | + return self.handle_no_permission() | |
194 | + return super(DeleteExam, self).dispatch(*args, **kwargs) | |
195 | + | |
196 | + | |
197 | + def get_context_data(self, **kwargs): | |
198 | + context = super(DeleteExam, self).get_context_data(**kwargs) | |
199 | + context['course'] = self.object.topic.subject.course | |
200 | + context['subject'] = self.object.topic.subject | |
201 | + context['exam'] = self.object | |
202 | + context['subjects'] = self.object.topic.subject.course.subjects.filter(Q(visible=True) | Q(professors__in=[self.request.user])) | |
203 | + if (has_role(self.request.user,'system_admin')): | |
204 | + context['subjects'] = self.object.topic.subject.course.subjects.all() | |
97 | 205 | return context |
206 | + | |
207 | + def get_success_url(self): | |
208 | + return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug}) | ... | ... |