Commit 289e1517a04dd3fadd95f4d23fd7327405f3f91c
1 parent
ee830676
Exists in
master
and in
5 other branches
atualização do admin, form, model, url, views e permissions #171
Showing
7 changed files
with
127 additions
and
61 deletions
Show diff stats
exam/admin.py
| 1 | 1 | from django.contrib import admin |
| 2 | 2 | |
| 3 | -from .models import Exam, Answer | |
| 3 | +from .models import Exam, Answer, AnswersStudent | |
| 4 | 4 | |
| 5 | 5 | class ExamAdmin(admin.ModelAdmin): |
| 6 | 6 | list_display = ['name', 'slug','begin_date','limit_date'] |
| ... | ... | @@ -10,5 +10,10 @@ class AnswerAdmin(admin.ModelAdmin): |
| 10 | 10 | list_display = ['answer','order'] |
| 11 | 11 | search_fields = ['answer'] |
| 12 | 12 | |
| 13 | +class AnswersStudentAdmin(admin.ModelAdmin): | |
| 14 | + list_display = ['student','exam','answered_in'] | |
| 15 | + search_fields = ['student','exam'] | |
| 16 | + | |
| 13 | 17 | admin.site.register(Exam, ExamAdmin) |
| 14 | 18 | admin.site.register(Answer, AnswerAdmin) |
| 19 | +admin.site.register(AnswersStudent, AnswersStudentAdmin) | ... | ... |
exam/forms.py
| 1 | -from django.utils.translation import ugettext_lazy as _ | |
| 2 | 1 | from django import forms |
| 2 | +from django.utils.translation import ugettext_lazy as _ | |
| 3 | +from users.models import User | |
| 3 | 4 | from .models import Exam |
| 4 | 5 | |
| 5 | 6 | class ExamForm(forms.ModelForm): |
| 6 | - def clean_end_date(self): | |
| 7 | - begin_date = self.data['begin_date'] | |
| 8 | - limit_date = self.data['limit_date'] | |
| 9 | 7 | |
| 10 | - if begin_date and limit_date and limit_date < begin_date: | |
| 11 | - raise forms.ValidationError(_('The end date may not be before the start date.')) | |
| 12 | - return endDate | |
| 8 | + def __init__(self, *args, **kwargs): | |
| 9 | + super(ExamForm, self).__init__(*args, **kwargs) | |
| 10 | + self.fields["all_students"].required = False | |
| 11 | + self.fields["all_students"].initial = False | |
| 12 | + self.fields["students"].required = False | |
| 13 | + | |
| 14 | + def clean_all_students(self): | |
| 15 | + if('all_students' not in self.data): | |
| 16 | + if('students' in self.data): | |
| 17 | + return False | |
| 18 | + raise forms.ValidationError(_('It is required one these fields.')) | |
| 19 | + else: | |
| 20 | + all_students = self.data['all_students'] | |
| 21 | + if(not all_students): | |
| 22 | + raise forms.ValidationError(_('It is required one these fields.')) | |
| 23 | + return True | |
| 13 | 24 | |
| 14 | 25 | |
| 15 | - class Meta: | |
| 16 | - model = Exam | |
| 17 | - fields = ['name','begin_date','limit_date'] | |
| 26 | + class Meta: | |
| 27 | + model = Exam | |
| 28 | + fields = ['name','begin_date','limit_date','students','all_students'] | |
| 18 | 29 | |
| 19 | - widgets = { | |
| 20 | - 'name': forms.TextInput(attrs={'placeholder': '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')}), | |
| 23 | - } | |
| 30 | + widgets = { | |
| 31 | + 'name': forms.TextInput(attrs={'placeholder': 'Exam?'}), | |
| 32 | + 'begin_date': forms.DateTimeInput( | |
| 33 | + attrs={'placeholder': _('Start date to resolve the exam')}), | |
| 34 | + 'limit_date': forms.DateTimeInput( | |
| 35 | + attrs={'placeholder': _('Maximum date permited to resolve the exam')}), | |
| 36 | + 'student': forms.Select(), | |
| 37 | + } | ... | ... |
exam/models.py
| ... | ... | @@ -27,4 +27,18 @@ class Answer(models.Model): |
| 27 | 27 | verbose_name_plural = _('Answers') |
| 28 | 28 | |
| 29 | 29 | def __str__(self): |
| 30 | - return str(self.answer) + str("/") + str(self.poll) | |
| 30 | + return str(self.answer) + str("/") + str(self.exam) | |
| 31 | + | |
| 32 | +class AnswersStudent(models.Model): | |
| 33 | + status = models.BooleanField(_("Answered"), default=False) | |
| 34 | + exam = models.ForeignKey(Exam, verbose_name = _('Exam'), related_name='answers_stundet') | |
| 35 | + answer = models.ManyToManyField(Answer,verbose_name = _('Answers Students'), related_name='answers_stundet') | |
| 36 | + student = models.ForeignKey(User, verbose_name = _('Student'), related_name='answers_stundent') | |
| 37 | + answered_in = models.DateTimeField(_("Answered Date"),auto_now=True) | |
| 38 | + | |
| 39 | + class Meta: | |
| 40 | + verbose_name = _('Answer Stundent') | |
| 41 | + verbose_name_plural = _('Answers Student') | |
| 42 | + | |
| 43 | + def __str__(self): | |
| 44 | + return str(self.student) + str("/") + str(self.exam) | ... | ... |
exam/permissions.py
| ... | ... | @@ -10,3 +10,13 @@ def edit_exam(role, user, exam): |
| 10 | 10 | return True |
| 11 | 11 | |
| 12 | 12 | return False |
| 13 | + | |
| 14 | +@register_object_checker() | |
| 15 | +def delete_exam(role, user, exam): | |
| 16 | + if (role == SystemAdmin): | |
| 17 | + return True | |
| 18 | + | |
| 19 | + if (user in exam.topic.subject.professors.all()): | |
| 20 | + return True | |
| 21 | + | |
| 22 | + return False | ... | ... |
exam/urls.py
| ... | ... | @@ -3,8 +3,10 @@ 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_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'), | |
| 6 | + url(r'^create/(?P<slug>[\w\-_]+)/$', views.CreateExam.as_view(), name='create_exam'), # exam slug | |
| 7 | + url(r'^update/(?P<slug>[\w\-_]+)/$', views.UpdateExam.as_view(), name='update_exam'), # topic slug | |
| 8 | + url(r'^view/(?P<slug>[\w\-_]+)/$', views.ViewExam.as_view(), name='view_exam'), # exam slug | |
| 9 | + url(r'^delete/(?P<slug>[\w\-_]+)/$', views.DeleteExam.as_view(), name='delete_exam'), # exam | |
| 10 | + url(r'^answer/$', views.AnswerExam.as_view(), name='answer_exam'), # exam | |
| 11 | + url(r'^answer-exam/(?P<slug>[\w\-_]+)/$', views.AnswerStudentExam.as_view(), name='answer_student_exam'), # exam slug | |
| 10 | 12 | ] | ... | ... |
exam/views.py
| ... | ... | @@ -12,7 +12,7 @@ from django.db.models import Q |
| 12 | 12 | # from django.views.generic.edit import FormMixin |
| 13 | 13 | |
| 14 | 14 | from .forms import ExamForm |
| 15 | -from .models import Exam, Answer | |
| 15 | +from .models import Exam, Answer, AnswersStudent | |
| 16 | 16 | from core.mixins import NotificationMixin |
| 17 | 17 | from users.models import User |
| 18 | 18 | from courses.models import Course, Topic |
| ... | ... | @@ -26,51 +26,23 @@ class ViewExam(LoginRequiredMixin,generic.DetailView): |
| 26 | 26 | def get_object(self, queryset=None): |
| 27 | 27 | return get_object_or_404(Exam, slug = self.kwargs.get('slug')) |
| 28 | 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 | |
| 40 | - | |
| 41 | - def form_valid(self, form): | |
| 42 | - exam = self.object | |
| 43 | - exam = form.save(commit = False) | |
| 44 | - exam.answers.all().delete() | |
| 45 | - exam.save() | |
| 46 | - | |
| 47 | - | |
| 48 | - for key in self.request.POST: | |
| 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) | |
| 51 | - answer.save() | |
| 52 | - | |
| 53 | - return super(ViewExam, self).form_valid(form) | |
| 54 | - | |
| 55 | 29 | def get_context_data(self, **kwargs): |
| 56 | 30 | context = super(ViewExam, self).get_context_data(**kwargs) |
| 57 | 31 | exam = self.object |
| 32 | + context["topic"] = exam.topic | |
| 58 | 33 | context['course'] = exam.topic.subject.course |
| 59 | 34 | context['subject'] = exam.topic.subject |
| 60 | 35 | 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) | |
| 36 | + answered = AnswersStudent.objects.filter(exam = exam, student=self.request.user) | |
| 37 | + print (answered) | |
| 38 | + if answered.count()<1: | |
| 39 | + context['status'] = False | |
| 40 | + else: | |
| 41 | + context['status'] = answered[0].status | |
| 71 | 42 | return context |
| 72 | 43 | |
| 73 | 44 | |
| 45 | + | |
| 74 | 46 | class CreateExam(LoginRequiredMixin,HasRoleMixin,generic.CreateView): |
| 75 | 47 | |
| 76 | 48 | allowed_roles = ['professor', 'system_admin'] |
| ... | ... | @@ -80,7 +52,6 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin,generic.CreateView): |
| 80 | 52 | form_class = ExamForm |
| 81 | 53 | context_object_name = 'exam' |
| 82 | 54 | template_name = 'exam/create.html' |
| 83 | - success_url = reverse_lazy('core:home') | |
| 84 | 55 | |
| 85 | 56 | def form_invalid(self, form,**kwargs): |
| 86 | 57 | context = super(CreateExam, self).form_invalid(form) |
| ... | ... | @@ -92,6 +63,8 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin,generic.CreateView): |
| 92 | 63 | keys = sorted(answers) |
| 93 | 64 | context.context_data['answers'] = answers |
| 94 | 65 | context.context_data['keys'] = keys |
| 66 | + context.context_data['form'] = form | |
| 67 | + context.status_code = 400 | |
| 95 | 68 | return context |
| 96 | 69 | |
| 97 | 70 | def form_valid(self, form): |
| ... | ... | @@ -105,7 +78,7 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin,generic.CreateView): |
| 105 | 78 | answer = Answer(answer=self.request.POST[key],order=key,exam=self.object) |
| 106 | 79 | answer.save() |
| 107 | 80 | |
| 108 | - return super(CreatePoll, self).form_valid(form) | |
| 81 | + return self.render_to_response(self.get_context_data(form = form), status = 200) | |
| 109 | 82 | |
| 110 | 83 | def get_context_data(self, **kwargs): |
| 111 | 84 | context = super(CreateExam, self).get_context_data(**kwargs) |
| ... | ... | @@ -130,7 +103,7 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): |
| 130 | 103 | exam = get_object_or_404(Exam, slug = self.kwargs.get('slug')) |
| 131 | 104 | if(not has_object_permission('edit_exam', self.request.user, exam)): |
| 132 | 105 | return self.handle_no_permission() |
| 133 | - return super(UpdatePoll, self).dispatch(*args, **kwargs) | |
| 106 | + return super(UpdateExam, self).dispatch(*args, **kwargs) | |
| 134 | 107 | |
| 135 | 108 | def get_object(self, queryset=None): |
| 136 | 109 | return get_object_or_404(Exam, slug = self.kwargs.get('slug')) |
| ... | ... | @@ -145,6 +118,8 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): |
| 145 | 118 | keys = sorted(answers) |
| 146 | 119 | context.context_data['answers'] = answers |
| 147 | 120 | context.context_data['keys'] = keys |
| 121 | + context.context_data['form'] = form | |
| 122 | + context.status_code = 400 | |
| 148 | 123 | return context |
| 149 | 124 | |
| 150 | 125 | def form_valid(self, form): |
| ... | ... | @@ -206,3 +181,49 @@ class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): |
| 206 | 181 | |
| 207 | 182 | def get_success_url(self): |
| 208 | 183 | return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug}) |
| 184 | + | |
| 185 | +class AnswerExam(generic.TemplateView): | |
| 186 | + template_name = 'exam/answer.html' | |
| 187 | + | |
| 188 | +class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | |
| 189 | + | |
| 190 | + model = AnswersStudent | |
| 191 | + fields = ['status'] | |
| 192 | + context_object_name = 'answer' | |
| 193 | + template_name = 'exam/answer_student.html' | |
| 194 | + | |
| 195 | + def form_valid(self, form): | |
| 196 | + exam = get_object_or_404(Exam, slug = self.kwargs.get('slug')) | |
| 197 | + answers = AnswersStudent( | |
| 198 | + status = True, | |
| 199 | + exam = exam, | |
| 200 | + student = self.request.user, | |
| 201 | + ) | |
| 202 | + answers.save() | |
| 203 | + | |
| 204 | + for key in self.request.POST: | |
| 205 | + if(key != 'csrfmiddlewaretoken'): | |
| 206 | + answers.answer.add(exam.answers.all().filter(order=key)[0]) | |
| 207 | + | |
| 208 | + return self.render_to_response(self.get_context_data(form = form), status = 200) | |
| 209 | + | |
| 210 | + def get_context_data(self, **kwargs): | |
| 211 | + context = super(AnswerStudentExam, self).get_context_data(**kwargs) | |
| 212 | + print (self.kwargs.get('slug')) | |
| 213 | + exam = get_object_or_404(Exam, slug = self.kwargs.get('slug')) | |
| 214 | + context['exam'] = exam | |
| 215 | + context['topic'] = exam.topic | |
| 216 | + context['course'] = exam.topic.subject.course | |
| 217 | + context['subject'] = exam.topic.subject | |
| 218 | + context['subjects'] = exam.topic.subject.course.subjects.all() | |
| 219 | + | |
| 220 | + print (self.request.method) | |
| 221 | + answers = {} | |
| 222 | + for answer in exam.answers.all(): | |
| 223 | + answers[answer.order] = answer.answer | |
| 224 | + | |
| 225 | + keys = sorted(answers) | |
| 226 | + context['answers'] = answers | |
| 227 | + context['keys'] = keys | |
| 228 | + | |
| 229 | + return context | ... | ... |