Commit 7f4810ac5ea01c43af46fc595f18e62ad990ca63
1 parent
10885250
Exists in
master
and in
5 other branches
Criado o templete de criar enquete #77
Showing
8 changed files
with
248 additions
and
53 deletions
Show diff stats
core/models.py
| ... | ... | @@ -6,20 +6,20 @@ from autoslug.fields import AutoSlugField |
| 6 | 6 | |
| 7 | 7 | class Action(models.Model): |
| 8 | 8 | """ |
| 9 | - It represents an Action on the program by a User such as "create post", | |
| 9 | + It represents an Action on the program by a User such as "create post", | |
| 10 | 10 | "visualize post", etc. It is supposed to be created everytime we want an aciton |
| 11 | 11 | """ |
| 12 | 12 | |
| 13 | 13 | name = models.CharField(_('Name'), max_length = 100) |
| 14 | 14 | created_date = models.DateField(_('Created Date'), auto_now_add=True) |
| 15 | - | |
| 15 | + | |
| 16 | 16 | class Meta: |
| 17 | 17 | verbose_name = "Action" |
| 18 | 18 | verbose_name_plural = "Actions" |
| 19 | 19 | |
| 20 | 20 | def __str__(self): |
| 21 | 21 | return self.name |
| 22 | - | |
| 22 | + | |
| 23 | 23 | |
| 24 | 24 | class Resource(models.Model): |
| 25 | 25 | """ |
| ... | ... | @@ -27,38 +27,38 @@ class Resource(models.Model): |
| 27 | 27 | Example: Pool was answered (Resource: Pool), PDF was visualized(Resource: PDF). |
| 28 | 28 | |
| 29 | 29 | Attributes: |
| 30 | - @name: name of the resource affected, it will be unique because a resource can be affecte | |
| 30 | + @name: name of the resource affected, it will be unique because a resource can be affecte | |
| 31 | 31 | by a huge amount of actions |
| 32 | 32 | @created_date: The date the resource was created |
| 33 | 33 | @link: Which URL made that resource able to find |
| 34 | 34 | """ |
| 35 | 35 | |
| 36 | 36 | name = models.CharField(_('Name'), max_length =100) |
| 37 | - slug = AutoSlugField(_("Slug"), populate_from='name', unique=True, null=True) | |
| 37 | + slug = AutoSlugField(_("Slug"), populate_from='name', unique=True) | |
| 38 | 38 | created_date = models.DateField(_('Created Date'), auto_now_add=True) |
| 39 | 39 | url = models.CharField(_('URL'), max_length =100, default="") |
| 40 | 40 | |
| 41 | 41 | |
| 42 | 42 | class Meta: |
| 43 | 43 | verbose_name = "Resource" |
| 44 | - verbose_name_plural = "Resources" | |
| 44 | + verbose_name_plural = "Resources" | |
| 45 | 45 | |
| 46 | 46 | def __str__(self): |
| 47 | 47 | return self.name |
| 48 | 48 | |
| 49 | 49 | |
| 50 | 50 | class Action_Resource(models.Model): |
| 51 | - | |
| 51 | + | |
| 52 | 52 | action = models.ForeignKey(Action , verbose_name= _('Action_Applied')) |
| 53 | 53 | resource = models.ForeignKey(Resource, verbose_name = _('Resource')) |
| 54 | - | |
| 54 | + | |
| 55 | 55 | class Meta: |
| 56 | 56 | verbose_name = "Action_Resource" |
| 57 | 57 | verbose_name_plural = "Action_Resources" |
| 58 | 58 | |
| 59 | 59 | def __str__(self): |
| 60 | 60 | return ''.join([self.action.name, " / ", self.resource.name]) |
| 61 | - | |
| 61 | + | |
| 62 | 62 | |
| 63 | 63 | class Notification(models.Model): |
| 64 | 64 | """ |
| ... | ... | @@ -77,7 +77,7 @@ class Notification(models.Model): |
| 77 | 77 | datetime = models.DateTimeField(_("Date and Time of action"), auto_now_add = True) |
| 78 | 78 | action_resource = models.ForeignKey(Action_Resource, verbose_name = _('Action_Resource')) |
| 79 | 79 | actor = models.ForeignKey(User, related_name = _('%(class)s_Performer'), verbose_name= _('Perfomer'), null = True) |
| 80 | - | |
| 80 | + | |
| 81 | 81 | class Meta: |
| 82 | 82 | verbose_name = _("Notification") |
| 83 | 83 | verbose_name_plural = _("Notifications") | ... | ... |
poll/admin.py
| 1 | 1 | from django.contrib import admin |
| 2 | 2 | |
| 3 | -# Register your models here. | |
| 3 | +from .models import Poll, Answer | |
| 4 | + | |
| 5 | +class PollAdmin(admin.ModelAdmin): | |
| 6 | + list_display = ['name', 'slug','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(Poll, PollAdmin) | |
| 14 | +admin.site.register(Answer, AnswerAdmin) | ... | ... |
| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | +from django import forms | |
| 2 | +from django.utils.translation import ugettext_lazy as _ | |
| 3 | +from users.models import User | |
| 4 | +from .models import Poll | |
| 5 | + | |
| 6 | +class PollForm(forms.ModelForm): | |
| 7 | + | |
| 8 | + # password = forms.CharField(label=_('Password'), widget=forms.PasswordInput) | |
| 9 | + # password2 = forms.CharField(label = _('Password confirmation'), widget = forms.PasswordInput) | |
| 10 | + # birth_date = forms.DateField(widget=forms.SelectDateWidget()) | |
| 11 | + # MIN_LENGTH = 8 | |
| 12 | + | |
| 13 | + class Meta: | |
| 14 | + model = Poll | |
| 15 | + # exclude = ['is_staff', 'is_active'] | |
| 16 | + fields = ['name','limit_date'] | |
| 17 | + | |
| 18 | + widgets = { | |
| 19 | + 'name': forms.TextInput(attrs={'placeholder': 'Question?'}), | |
| 20 | + 'description': forms.DateTimeInput( | |
| 21 | + attrs={'placeholder': 'Maximum date permited to resolve the poll'}), | |
| 22 | + } | ... | ... |
poll/templates/poll/poll.html
| 1 | 1 | {% extends "topic/index.html" %} |
| 2 | 2 | |
| 3 | -{% load i18n %} | |
| 3 | +{% load i18n widget_tweaks dict_access static%} | |
| 4 | 4 | |
| 5 | 5 | {% block style %} |
| 6 | 6 | <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> |
| 7 | 7 | {% endblock %} |
| 8 | 8 | |
| 9 | 9 | {% block content %} |
| 10 | -<div class="col-md-8 col-md-offset-2"> | |
| 11 | - <div class="panel panel-primary"> | |
| 12 | - <div class="panel-heading"> | |
| 13 | - <h3 class="panel-title"> | |
| 14 | - <span class="glyphicon glyphicon-hand-right"></span> Question?</h3> | |
| 10 | +<!-- Modal (remember to change the ids!!!) --> | |
| 11 | +<div class="modal fade" id="poll" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |
| 12 | + <div class="modal-dialog" role="document"> | |
| 13 | + <div class="modal-content"> | |
| 14 | + | |
| 15 | + <!-- Modal Header --> | |
| 16 | + <div class="modal-header"> | |
| 17 | + | |
| 18 | + <!-- Put your title here!!! --> | |
| 19 | + <h4 class="modal-title" id="myModalLabel">{% trans "Create a Poll" %}</h4> | |
| 20 | + | |
| 15 | 21 | </div> |
| 16 | - <div class="container-fluid"> | |
| 17 | - <form id="form" class="" action="" method="post"> | |
| 18 | - <div class="row form-group"> | |
| 19 | - <div class="col-md-1"> | |
| 20 | - </br> | |
| 21 | - <label><a href=""><span class="glyphicon glyphicon-move"></span></a></label> | |
| 22 | - </div> | |
| 23 | - <div class="col-md-10"> | |
| 24 | - <div class="form-control-md has-success is-empty"> | |
| 25 | - <input type="text" class="form-control" placeholder="Email address default size"> | |
| 26 | - <span class="help-block">{% trans "Possible Answer" %}</span> | |
| 22 | + <!-- Modal Body --> | |
| 23 | + <div class="modal-body"> | |
| 24 | + | |
| 25 | + <!-- Put ONLY your content here!!! --> | |
| 26 | + <div class="conteiner"> | |
| 27 | + <div class="row form-group"> | |
| 28 | + <div class="col-md-1"> | |
| 29 | + </br> | |
| 30 | + <label><span class="glyphicon glyphicon-hand-right"></span></label> | |
| 31 | + </div> | |
| 32 | + <div class="col-md-10"> | |
| 33 | + <div class="has-success"> | |
| 34 | + <input form="form" type="text" name="{{form.name.name}}" {% if form.name.value != None %}value="{{form.name.value}}" {% endif %} class="form-control" placeholder='{% trans "Question?" %}'> | |
| 35 | + <span class="help-block">{% trans "A Question to be answered" %}</span> | |
| 36 | + </div> | |
| 37 | + </div> | |
| 38 | + {% if form.name.errors %} | |
| 39 | + <div class="col-md-10 not_submited"> | |
| 40 | + </br> | |
| 41 | + <div class="alert alert-danger alert-dismissible" role="alert"> | |
| 42 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
| 43 | + <span aria-hidden="true">×</span> | |
| 44 | + </button> | |
| 45 | + <ul> | |
| 46 | + {% for error in form.name.errors %} | |
| 47 | + <li>{{ error }}</li> | |
| 48 | + {% endfor %} | |
| 49 | + </ul> | |
| 50 | + </div> | |
| 51 | + </div> | |
| 52 | + {% endif %} | |
| 53 | + </div> | |
| 54 | + <form id="form" class="" action="" method="post"> | |
| 55 | + {% csrf_token %} | |
| 56 | + {% for key in keys %} | |
| 57 | + <div class="row form-group"> | |
| 58 | + <div class="col-md-1"> | |
| 59 | + </br> | |
| 60 | + <label><span class="glyphicon glyphicon-move"></span></label> | |
| 61 | + </div> | |
| 62 | + <div class="col-md-10"> | |
| 63 | + <div class="has-success is-empty"> | |
| 64 | + <input type="text" name="{{key}}" class="form-control" placeholder='{% trans "Answer" %}' value="{{ answers|value:key }}"> | |
| 65 | + <span class="help-block">{% trans "Possible answer for the question" %}</span> | |
| 66 | + </div> | |
| 67 | + </div> | |
| 68 | + <div class="col-md-1"> | |
| 69 | + </br> | |
| 70 | + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label> | |
| 71 | + </div> | |
| 72 | + </div> | |
| 73 | + {% empty %} | |
| 74 | + <div class="row form-group"> | |
| 75 | + <div class="col-md-1"> | |
| 76 | + </br> | |
| 77 | + <label><span class="glyphicon glyphicon-move"></span></label> | |
| 78 | + </div> | |
| 79 | + <div class="col-md-10"> | |
| 80 | + <div class="has-success is-empty"> | |
| 81 | + <input type="text" name="1" class="form-control" placeholder='{% trans "Answer" %}'> | |
| 82 | + <span class="help-block">{% trans "Possible answer for the question" %}</span> | |
| 83 | + </div> | |
| 84 | + </div> | |
| 85 | + <div class="col-md-1"> | |
| 86 | + </br> | |
| 87 | + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label> | |
| 88 | + </div> | |
| 89 | + </div> | |
| 90 | + {% endfor %} | |
| 91 | + </form> | |
| 92 | + </br> | |
| 93 | + </div> | |
| 94 | + <button type="button" id="add" class="btn btn-primary btn-block btn-sm">add</button> | |
| 95 | + <div class="row form-group"> | |
| 96 | + <input form="form" class="form-control" type="date" name="{{form.limit_date.name}}" {% if form.limit_date.value != None %}value="{{form.limit_date.value}}"{% endif %}> | |
| 97 | + {% if form.limit_date.errors %} | |
| 98 | + <div class="not_submited"> | |
| 99 | + </br> | |
| 100 | + <div class="alert alert-danger alert-dismissible" role="alert"> | |
| 101 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
| 102 | + <span aria-hidden="true">×</span> | |
| 103 | + </button> | |
| 104 | + <ul> | |
| 105 | + {% for error in form.limit_date.errors %} | |
| 106 | + <li>{{ error }}</li> | |
| 107 | + {% endfor %} | |
| 108 | + </ul> | |
| 27 | 109 | </div> |
| 28 | - </div> | |
| 29 | - <div class="col-md-1"> | |
| 30 | - </br> | |
| 31 | - <label><a href=""><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></a></label> | |
| 32 | - </div> | |
| 33 | 110 | </div> |
| 34 | - </form> | |
| 35 | - </br> | |
| 111 | + {% endif %} | |
| 112 | + </div> | |
| 113 | + | |
| 114 | + </div> | |
| 115 | + | |
| 116 | + <!-- Modal Footer --> | |
| 117 | + <div class="modal-footer"> | |
| 118 | + | |
| 119 | + <!-- Don't remove that!!! --> | |
| 120 | + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> | |
| 121 | + | |
| 122 | + <!-- Put curtom buttons here!!! --> | |
| 123 | + <button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Create" %}</button> | |
| 36 | 124 | </div> |
| 37 | 125 | |
| 38 | - </div> | |
| 39 | - <div class="panel-footer text-center"> | |
| 40 | - <button type="button" id="add" class="btn btn-primary btn-block btn-sm">add</button> | |
| 41 | - </div> | |
| 42 | 126 | </div> |
| 127 | + </div> | |
| 128 | +</div> | |
| 43 | 129 | <script type="text/javascript"> |
| 44 | -$( "#form" ).sortable({ | |
| 130 | +// Este js tem que ficar aqui se não a tag "trans" não vai funcionar | |
| 131 | +$(window).ready(function() { // utilizado para abrir o modal quando tiver tido algum erro no preenchimento do formulario | |
| 132 | + if($('.not_submited').length){ | |
| 133 | + $('#poll').modal('show'); | |
| 134 | + } | |
| 135 | +}); | |
| 136 | +$( "#form" ).sortable({ // utilizado para fazer a re-organização das respostas | |
| 45 | 137 | delay: 100, |
| 46 | 138 | distance: 5, |
| 139 | + update: function( event, ui ) { | |
| 140 | + var cont = 1; | |
| 141 | + $("#form div div div input").each(function(){ | |
| 142 | + $(this).attr('name',cont++); | |
| 143 | + }); | |
| 144 | + }, | |
| 47 | 145 | }); |
| 48 | -$("#add").click(function() { | |
| 49 | - $("#form").append('<div class="row form-group"><div class="col-md-1"></br><label><a href=""><span class="glyphicon glyphicon-move"></span></a></label></div><div class="col-md-10"><div class="form-group-md has-success is-empty"><input type="text" class="form-control" placeholder="Email address default size"><span class="help-block">Please enter a valid email address</span></div></div><div class="col-md-1"></br><label><a href=""><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></a></label></div></br></div>'); | |
| 146 | +name = 2; | |
| 147 | +$("#add").click(function() { // utilizado para adicionar um novo campo de resposta | |
| 148 | + //Obs: não funcionar se estiver importado no head, só funciona se estiver no final do arquivo | |
| 149 | + $("#form").append('\ | |
| 150 | + <div class="row form-group">\ | |
| 151 | + <div class="col-md-1">\ | |
| 152 | + </br>\ | |
| 153 | + <label><span class="glyphicon glyphicon-move"></span></label>\ | |
| 154 | + </div>\ | |
| 155 | + <div class="col-md-10">\ | |
| 156 | + <div class="has-success is-empty">\ | |
| 157 | + <input type="text" name="1" class="form-control" placeholder="{% trans "Answer" %}">\ | |
| 158 | + <span class="help-block">{% trans "Possible answer for the question" %}</span>\ | |
| 159 | + </div>\ | |
| 160 | + </div>\ | |
| 161 | + <div class="col-md-1">\ | |
| 162 | + </br>\ | |
| 163 | + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>\ | |
| 164 | + </div>\ | |
| 165 | + </div>'); | |
| 166 | + var cont = 1; | |
| 167 | + $("#form div div div input").each(function(){ | |
| 168 | + $(this).attr('name',cont++); | |
| 169 | + }); | |
| 50 | 170 | }); |
| 51 | 171 | </script> |
| 172 | +<a href="" data-toggle="modal" data-target="#poll">modal</a> | |
| 52 | 173 | {% endblock content %} | ... | ... |
poll/urls.py
poll/views.py
| ... | ... | @@ -8,31 +8,59 @@ 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.views.generic.edit import FormMixin | |
| 11 | 12 | |
| 12 | -# from .forms import CourseForm, UpdateCourseForm, CategoryForm, SubjectForm,TopicForm | |
| 13 | -# from .models import Course, Subject, Category,Topic, SubjectCategory | |
| 13 | +from .forms import PollForm | |
| 14 | +from .models import Poll, Answer | |
| 14 | 15 | from core.mixins import NotificationMixin |
| 15 | 16 | from users.models import User |
| 16 | -from courses.models import Course | |
| 17 | +from courses.models import Course, Topic | |
| 17 | 18 | |
| 18 | -class Poll(generic.TemplateView): | |
| 19 | +class CreatePoll(generic.CreateView): | |
| 19 | 20 | |
| 20 | 21 | # login_url = reverse_lazy("core:home") |
| 21 | 22 | # redirect_field_name = 'next' |
| 22 | - # model = Course | |
| 23 | - # context_object_name = 'course' | |
| 23 | + model = Poll | |
| 24 | + form_class = PollForm | |
| 25 | + context_object_name = 'poll' | |
| 24 | 26 | template_name = 'poll/poll.html' |
| 25 | 27 | # queryset = Course.objects.all() |
| 26 | - | |
| 28 | + success_url = reverse_lazy('core:home') | |
| 27 | 29 | # def get_queryset(self): |
| 28 | 30 | # return Course.objects.all()[0] |
| 29 | 31 | |
| 32 | + def form_invalid(self, form,**kwargs): | |
| 33 | + context = super(CreatePoll, self).form_invalid(form) | |
| 34 | + answers = {} | |
| 35 | + for key in self.request.POST: | |
| 36 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date'): | |
| 37 | + answers[key] = self.request.POST[key] | |
| 38 | + | |
| 39 | + keys = sorted(answers) | |
| 40 | + context.context_data['answers'] = answers | |
| 41 | + context.context_data['keys'] = keys | |
| 42 | + return context | |
| 43 | + | |
| 44 | + def form_valid(self, form): | |
| 45 | + self.object = form.save(commit = False) | |
| 46 | + topic = Topic.objects.all()[0] | |
| 47 | + self.object.student = self.request.user | |
| 48 | + self.object.question = "question" | |
| 49 | + self.object.topic = topic | |
| 50 | + self.object.save() | |
| 51 | + | |
| 52 | + for key in self.request.POST: | |
| 53 | + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date'): | |
| 54 | + answer = Answer(answer=self.request.POST[key],order=key,poll=self.object) | |
| 55 | + answer.save() | |
| 56 | + | |
| 57 | + return super(CreatePoll, self).form_valid(form) | |
| 58 | + | |
| 30 | 59 | def get_context_data(self, **kwargs): |
| 31 | - context = super(Poll, self).get_context_data(**kwargs) | |
| 60 | + context = super(CreatePoll, self).get_context_data(**kwargs) | |
| 32 | 61 | course = Course.objects.all()[0] |
| 62 | + # print (self.object) | |
| 33 | 63 | context['course'] = course |
| 34 | 64 | context['subject'] = course.subjects.all()[0] |
| 35 | 65 | context['subjects'] = course.subjects.all() |
| 36 | - # if (has_role(self.request.user,'system_admin')): | |
| 37 | - # context['subjects'] = self.object.course.subjects.all() | |
| 38 | 66 | return context | ... | ... |