Commit a8c49bea2f60ab26be5b81ffd2d5d56bd646695a

Authored by Gustavo Bernardo
2 parents 21009245 69a44a79

Merge branch 'dev' of https://github.com/amadeusproject/amadeuslms into dev

Showing 54 changed files with 870 additions and 403 deletions   Show diff stats
amadeus/local_settings.py.example
@@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
1 -import os  
2 -  
3 -DEBUG = True  
4 -  
5 -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  
6 -  
7 -DATABASES = {  
8 - 'default': {  
9 - 'ENGINE': 'django.db.backends.postgresql',  
10 - 'NAME': 'amadeus',  
11 - 'USER': 'amadeus_admin',  
12 - 'PASSWORD': 'amadeus',  
13 - 'HOST': '127.0.0.1',  
14 - 'PORT': '5432',  
15 - }  
16 -}  
17 \ No newline at end of file 0 \ No newline at end of file
amadeus/settings.py
@@ -55,8 +55,8 @@ INSTALLED_APPS = [ @@ -55,8 +55,8 @@ INSTALLED_APPS = [
55 'courses', 55 'courses',
56 'forum', 56 'forum',
57 'poll', 57 'poll',
58 - 'avaliacao',  
59 'links', 58 'links',
  59 + 'exam',
60 60
61 ] 61 ]
62 62
avaliacao/__init__.py
avaliacao/admin.py
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -from django.contrib import admin  
2 -  
3 -# Register your models here.  
avaliacao/apps.py
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -from django.apps import AppConfig  
2 -  
3 -  
4 -class AvaliacaoConfig(AppConfig):  
5 - name = 'avaliacao'  
avaliacao/migrations/0001_initial.py 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-10-05 13:38
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +import django.db.models.deletion
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + initial = True
  12 +
  13 + dependencies = [
  14 +
  15 + ('courses', '0002_subject_students'),
  16 + ]
  17 +
  18 + operations = [
  19 + migrations.CreateModel(
  20 + name='Avaliacao',
  21 + fields=[
  22 + ('activity_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='courses.Activity')),
  23 + ('name_avalicao', models.CharField(max_length=100, verbose_name='Name')),
  24 + ('init_date', models.DateField(verbose_name='Begin of Avaliacao Date')),
  25 + ('end_date', models.DateField(verbose_name='End of Avaliacao Date')),
  26 + ],
  27 + options={
  28 + 'verbose_name': 'Avaliacao',
  29 + 'verbose_name_plural': 'Avaliacoes',
  30 + },
  31 + bases=('courses.activity',),
  32 + ),
  33 + ]
avaliacao/migrations/__init__.py
avaliacao/models.py
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -from django.utils.translation import ugettext_lazy as _  
2 -from django.db import models  
3 -from autoslug.fields import AutoSlugField  
4 -from users.models import User  
5 -from core.models import Resource  
6 -from courses.models import Activity  
7 -  
8 -class Avaliacao(Activity):  
9 -  
10 - name_avalicao = models.CharField(_('Name'), max_length = 100)  
11 - init_date = models.DateField(_('Begin of Avaliacao Date'))  
12 - end_date = models.DateField(_('End of Avaliacao Date'))  
13 -  
14 - class Meta:  
15 - #ordering = ('create_date','name')  
16 - verbose_name = _('Avaliacao')  
17 - verbose_name_plural = _('Avaliacoes')  
18 -  
19 -def __str__(self):  
20 - return str(self.name) + str("/") + str(self.topic)  
avaliacao/tests.py
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -from django.test import TestCase  
2 -  
3 -# Create your tests here.  
avaliacao/urls.py
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -from django.conf.urls import url  
2 -  
3 -from . import views  
4 -  
5 -urlpatterns =[  
6 -  
7 -]  
avaliacao/views.py
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -from django.shortcuts import render  
2 -  
3 -# Create your views here.  
core/static/css/base/amadeus.css
@@ -321,4 +321,9 @@ body .container .jumbotron-inverse, body .container .well-inverse, body .contain @@ -321,4 +321,9 @@ body .container .jumbotron-inverse, body .container .well-inverse, body .contain
321 background-color: #FF0000; 321 background-color: #FF0000;
322 } 322 }
323 323
  324 +.img-list-user{
  325 + width: 150px;
  326 + height: 150px;
  327 +}
  328 +
324 .datepicker{z-index:9999 !important} 329 .datepicker{z-index:9999 !important}
325 \ No newline at end of file 330 \ No newline at end of file
core/static/img/female_avatar.png 0 → 100644

30.5 KB

core/static/img/male_avatar.png 0 → 100644

28.8 KB

courses/migrations/0002_subject_students.py 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-10-05 21:02
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + dependencies = [
  12 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  13 + ('courses', '0001_initial'),
  14 + ]
  15 +
  16 + operations = [
  17 + migrations.AddField(
  18 + model_name='subject',
  19 + name='students',
  20 + field=models.ManyToManyField(related_name='subject_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  21 + ),
  22 + ]
courses/models.py
@@ -54,7 +54,8 @@ class Subject(models.Model): @@ -54,7 +54,8 @@ class Subject(models.Model):
54 create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True) 54 create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True)
55 update_date = models.DateTimeField(_('Date of last update'), auto_now=True) 55 update_date = models.DateTimeField(_('Date of last update'), auto_now=True)
56 course = models.ForeignKey(Course, verbose_name = _('Course'), related_name="subjects") 56 course = models.ForeignKey(Course, verbose_name = _('Course'), related_name="subjects")
57 - professors = models.ManyToManyField(User,verbose_name=_('Professors'), related_name='subjects') 57 + professors = models.ManyToManyField(User,verbose_name=_('Professors'), related_name='professors_subjects')
  58 + students = models.ManyToManyField(User,verbose_name=_('Students'), related_name='subject_student')
58 59
59 60
60 class Meta: 61 class Meta:
courses/templates/course/index.html
@@ -54,17 +54,16 @@ @@ -54,17 +54,16 @@
54 {% endif %} 54 {% endif %}
55 55
56 <div class="col-md-12"> 56 <div class="col-md-12">
57 - <div class="input-group">  
58 - <div class="form-group is-empty"><input type="search" class="form-control" placeholder="Search Courses"></div>  
59 - <span class="input-group-btn input-group-sm">  
60 - <button type="button" class="btn btn-fab btn-fab-mini">  
61 - <i class="material-icons">search</i>  
62 - </button>  
63 - </span>  
64 - </div> 57 + <div class="input-group">
  58 + <div class="form-group is-empty"><input type="search" class="form-control" placeholder="Search Courses"></div>
  59 + <span class="input-group-btn input-group-sm">
  60 + <button type="button" class="btn btn-fab btn-fab-mini">
  61 + <i class="material-icons">search</i>
  62 + </button>
  63 + </span>
65 </div> 64 </div>
  65 +</div>
66 {% if user|has_role:'professor, system_admin' %} 66 {% if user|has_role:'professor, system_admin' %}
67 -  
68 <div class="col-md-12"> 67 <div class="col-md-12">
69 {% if courses|length > 0 %} 68 {% if courses|length > 0 %}
70 {% for course in courses_teacher %} 69 {% for course in courses_teacher %}
@@ -140,10 +139,7 @@ @@ -140,10 +139,7 @@
140 </div> 139 </div>
141 </div> 140 </div>
142 </div> 141 </div>
143 -{% endif %}  
144 -  
145 -{% if user|has_role:'students' %}  
146 - 142 +{% else %}
147 {% if courses|length > 0 %} 143 {% if courses|length > 0 %}
148 {% for course in courses_student %} 144 {% for course in courses_student %}
149 <div class="col-md-12"> 145 <div class="col-md-12">
courses/templates/course/view.html
@@ -52,16 +52,10 @@ @@ -52,16 +52,10 @@
52 <div class="panel panel-info"> 52 <div class="panel panel-info">
53 <div class="panel-heading headingOne"> 53 <div class="panel-heading headingOne">
54 <div class="row"> 54 <div class="row">
55 - <div class="col-xs-8 col-md-9 titleTopic"> 55 + <div class="col-xs-8 col-md-10 titleTopic">
56 <h4>{{course}}</h4> 56 <h4>{{course}}</h4>
57 </div> 57 </div>
58 - <div class="col-xs-4 col-md-3" id="divMoreActions">  
59 - <div class="btn-group">  
60 - <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">  
61 - <i class="fa fa-eye fa-2x" aria-hidden="true"></i>  
62 - </button>  
63 -  
64 - </div> 58 + <div class="col-xs-4 col-md-2" id="divMoreActions">
65 <div class="btn-group"> 59 <div class="btn-group">
66 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 60 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
67 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> 61 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
@@ -190,17 +184,12 @@ @@ -190,17 +184,12 @@
190 <div class="panel panel-info"> 184 <div class="panel panel-info">
191 <div class="panel-heading headingTwo ui-sortable-handle" role="tab"> 185 <div class="panel-heading headingTwo ui-sortable-handle" role="tab">
192 <div class="row"> 186 <div class="row">
193 - <div class="col-xs-9 col-md-9 titleTopic"> 187 + <div class="col-xs-9 col-md-10 titleTopic">
194 <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseTwo" aria-expanded="true" aria-controls="collapseTwo"> 188 <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
195 <h4 style="color:white">{{subject.name}}</h4> 189 <h4 style="color:white">{{subject.name}}</h4>
196 </a> 190 </a>
197 </div> 191 </div>
198 - <div class="col-xs-3 col-md-3" id="divMoreActions">  
199 - <div class="btn-group">  
200 - <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">  
201 - <i class="fa fa-eye fa-2x" aria-hidden="true"></i>  
202 - </button>  
203 - </div> 192 + <div class="col-xs-3 col-md-2" id="divMoreActions">
204 <div class="btn-group"> 193 <div class="btn-group">
205 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 194 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
206 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> 195 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
courses/templates/subject/form_view_teacher.html
@@ -11,8 +11,22 @@ @@ -11,8 +11,22 @@
11 <div class="col-md-9 col-sm-9"> 11 <div class="col-md-9 col-sm-9">
12 <h3>{{ topic }}</h3> 12 <h3>{{ topic }}</h3>
13 </div> 13 </div>
14 - <div class="col-md-3 col-sm-3">  
15 - <a href="{% url 'course:update_topic' topic.slug%}" class="btn">{% trans "edit" %}</a> 14 + <div class="col-xs-4 col-md-3 divMoreActions">
  15 + <div class="btn-group">
  16 + <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">
  17 + <i class="fa fa-eye fa-2x" aria-hidden="true"></i>
  18 + </button>
  19 + </div>
  20 + <div class="btn-group">
  21 + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  22 + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
  23 + </button>
  24 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  25 + <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li>
  26 + <li><a href="{% url 'course:update_subject' subject.slug %}" data-toggle="modal" data-target="#editSubject"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li>
  27 + <li><a href="{% url 'course:delete_subject' subject.slug %}" data-toggle="modal" data-target="#removeSubject"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li>
  28 + </ul>
  29 + </div>
16 </div> 30 </div>
17 </div> 31 </div>
18 </div> 32 </div>
courses/templates/subject/index.html
@@ -36,19 +36,28 @@ @@ -36,19 +36,28 @@
36 <div class="panel panel-info"> 36 <div class="panel panel-info">
37 <div class="panel-heading"> 37 <div class="panel-heading">
38 <div class="row"> 38 <div class="row">
39 - <div class="col-md-7 col-sm-7"> 39 + <div class="col-md-9 col-sm-7">
40 <h3>{{subject}}</h3> 40 <h3>{{subject}}</h3>
41 </div> 41 </div>
42 - <div class="col-md-2 col-sm-2">  
43 - {% if user|has_role:'system_admin' or user in subject.professors %}  
44 - <a href="{% url 'course:update_subject' subject.slug%}" class="btn">{% trans "edit" %}</a>  
45 - {% endif %}  
46 - </div>  
47 - <div class="col-md-3 col-sm-3">  
48 - {% if user|has_role:'system_admin' or user in subject.professors %}  
49 - <a href="{% url 'course:delete_subject' subject.slug%}" class="btn">{% trans "delete" %}</a>  
50 - {% endif %}  
51 - </div> 42 + <div class="col-xs-4 col-md-3 divMoreActions">
  43 + <div class="btn-group">
  44 + <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">
  45 + <i class="fa fa-eye fa-2x" aria-hidden="true"></i>
  46 + </button>
  47 + </div>
  48 + {% if user|has_role:'system_admin' or user in subject.professors %}
  49 + <div class="btn-group">
  50 + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  51 + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
  52 + </button>
  53 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  54 + <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li>
  55 + <li><a href="{% url 'course:update_subject' subject.slug %}" data-toggle="modal" data-target="#editSubject"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li>
  56 + <li><a href="{% url 'course:delete_subject' subject.slug %}" data-toggle="modal" data-target="#removeSubject"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li>
  57 + </ul>
  58 + </div>
  59 + {% endif %}
  60 + </div>
52 </div> 61 </div>
53 </div> 62 </div>
54 <div class="panel-body"> 63 <div class="panel-body">
courses/templates/topic/index.html
@@ -50,19 +50,23 @@ @@ -50,19 +50,23 @@
50 <div class="panel panel-info"> 50 <div class="panel panel-info">
51 <div class="panel-heading"> 51 <div class="panel-heading">
52 <div class="row"> 52 <div class="row">
53 - <div class="col-md-7 col-sm-7"> 53 + <div class="col-md-10 col-sm-7">
54 <h3>{{subject}}</h3> 54 <h3>{{subject}}</h3>
55 </div> 55 </div>
56 - <div class="col-md-2 col-sm-2">  
57 - {% if user|has_role:'system_admin' or user in subject.professors %}  
58 - <a href="{% url 'course:update_subject' subject.slug%}" class="btn">{% trans "edit" %}</a>  
59 - {% endif %}  
60 - </div>  
61 - <div class="col-md-3 col-sm-3">  
62 - {% if user|has_role:'system_admin' or user in subject.professors %}  
63 - <a href="{% url 'course:delete_subject' subject.slug%}" class="btn">{% trans "delete" %}</a>  
64 - {% endif %}  
65 - </div> 56 + <div class="col-xs-4 col-md-2 divMoreActions">
  57 + {% if user|has_role:'system_admin' or user in subject.professors %}
  58 + <div class="btn-group">
  59 + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  60 + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
  61 + </button>
  62 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  63 + <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li>
  64 + <li><a href="{% url 'course:update_subject' subject.slug %}" data-toggle="modal" data-target="#editSubject"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li>
  65 + <li><a href="{% url 'course:delete_subject' subject.slug %}" data-toggle="modal" data-target="#removeSubject"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li>
  66 + </ul>
  67 + </div>
  68 + {% endif %}
  69 + </div>
66 </div> 70 </div>
67 </div> 71 </div>
68 <div class="panel-body"> 72 <div class="panel-body">
@@ -108,11 +112,10 @@ @@ -108,11 +112,10 @@
108 </div> 112 </div>
109 {% else %} 113 {% else %}
110 <div class="col-md-4"> 114 <div class="col-md-4">
111 - <input type="hidden" name="id" value="">  
112 - <input type="hidden" name="student" value=""> 115 + <!--<input type="hidden" name="id" value="">
  116 + <input type="hidden" name="student" value="">-->
113 <div class="form-group {% if form.pdf.errors %} has-error {% endif %}"> 117 <div class="form-group {% if form.pdf.errors %} has-error {% endif %}">
114 - <label for="id_pdf">PDF</label>  
115 - {{form.pdf}} 118 + {{ form.as_p }}
116 </div> 119 </div>
117 <button type="submit" class="btn btn-success" id="send_button">Enviar</button> 120 <button type="submit" class="btn btn-success" id="send_button">Enviar</button>
118 </div> 121 </div>
courses/urls.py
@@ -26,5 +26,4 @@ urlpatterns = [ @@ -26,5 +26,4 @@ urlpatterns = [
26 26
27 url(r'^forum/', include('forum.urls', namespace = 'forum')), 27 url(r'^forum/', include('forum.urls', namespace = 'forum')),
28 url(r'^poll/', include('poll.urls', namespace = 'poll')), 28 url(r'^poll/', include('poll.urls', namespace = 'poll')),
29 - url(r'^avaliacao/', include('avaliacao.urls', namespace = 'avaliacao'))  
30 ] 29 ]
courses/views.py
@@ -292,7 +292,7 @@ class TopicsView(LoginRequiredMixin, generic.ListView): @@ -292,7 +292,7 @@ class TopicsView(LoginRequiredMixin, generic.ListView):
292 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) 292 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
293 context = super(TopicsView, self).get_context_data(**kwargs) 293 context = super(TopicsView, self).get_context_data(**kwargs)
294 activitys = Activity.objects.filter(topic__name = topic.name) 294 activitys = Activity.objects.filter(topic__name = topic.name)
295 - students_activit = User.objects.filter(activities = Activity.objects.all()) 295 + students_activit = User.objects.filter(activities__in = Activity.objects.all())
296 # page_user = User.objects.get(id= self.kwargs['user_id']) 296 # page_user = User.objects.get(id= self.kwargs['user_id'])
297 context['topic'] = topic 297 context['topic'] = topic
298 context['subject'] = topic.subject 298 context['subject'] = topic.subject
exam/__init__.py 0 → 100644
exam/admin.py 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +from django.contrib import admin
  2 +
  3 +# Register your models here.
exam/apps.py 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +from django.apps import AppConfig
  2 +
  3 +
  4 +class ExamConfig(AppConfig):
  5 + name = 'exam'
exam/forms.py 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +from django import forms
  2 +from .models import Exam
  3 +
  4 +class ExamForm(forms.ModelForm):
  5 + def clean_end_date(self):
  6 + beginDate = self.data['beginDate']
  7 + endDate = self.data['endDate']
  8 +
  9 + if beginDate and endDate and endDate < beginDate:
  10 + raise forms.ValidationError(_('The end date may not be before the start date.'))
  11 + return endDate
  12 +
  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 +
  31 + class Meta:
  32 + model = Exam
  33 + fields = ['name','beginDate','endDate']
  34 +
  35 + widgets = {
  36 + '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'}),
  39 + }
exam/migrations/0001_initial.py 0 → 100644
@@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-10-06 19:57
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +import django.db.models.deletion
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + initial = True
  12 +
  13 + dependencies = [
  14 + ]
  15 +
  16 + operations = [
  17 + migrations.CreateModel(
  18 + name='Answer',
  19 + fields=[
  20 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  21 + ('answer', models.CharField(max_length=200, verbose_name='Answer')),
  22 + ('order', models.PositiveSmallIntegerField(verbose_name='Order')),
  23 + ],
  24 + options={
  25 + 'verbose_name_plural': 'Answers',
  26 + 'ordering': ('order',),
  27 + 'verbose_name': 'Answer',
  28 + },
  29 + ),
  30 + migrations.CreateModel(
  31 + name='Exam',
  32 + fields=[
  33 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  34 + ('name', models.CharField(max_length=100, verbose_name='Name')),
  35 + ('beginDate', models.DateTimeField(auto_now_add=True, verbose_name='Start Date')),
  36 + ('endDate', models.DateTimeField(auto_now=True, verbose_name='Date of last update')),
  37 + ],
  38 + options={
  39 + 'verbose_name_plural': 'Exams',
  40 + 'verbose_name': 'Exam',
  41 + },
  42 + ),
  43 + migrations.AddField(
  44 + model_name='answer',
  45 + name='exam',
  46 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='exam.Exam', verbose_name='Answers'),
  47 + ),
  48 + ]
exam/migrations/__init__.py 0 → 100644
exam/models.py 0 → 100644
@@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
  1 +from django.utils.translation import ugettext_lazy as _
  2 +from django.db import models
  3 +from autoslug.fields import AutoSlugField
  4 +from users.models import User
  5 +from core.models import Resource
  6 +from courses.models import Activity
  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)
  14 +
  15 + class Meta:
  16 + #ordering = ('create_date','name')
  17 + verbose_name = _('Exam')
  18 + verbose_name_plural = _('Exams')
  19 +
  20 + def __str__(self):
  21 + return str(self.name) + str("/") + str(self.topic)
  22 +
  23 +class Answer(models.Model):
  24 + answer = models.CharField(_("Answer"), max_length = 200)
  25 + order = models.PositiveSmallIntegerField(_("Order"))
  26 + exam = models.ForeignKey(Exam, verbose_name = _('Answers'), related_name='answers')
  27 +
  28 + class Meta:
  29 + ordering = ('order',)
  30 + verbose_name = _('Answer')
  31 + verbose_name_plural = _('Answers')
  32 +
  33 + def __str__(self):
  34 + return str(self.answer) + str("/") + str(self.poll)
exam/permisissions.py 0 → 100644
@@ -0,0 +1,12 @@ @@ -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/templatetags/__init__.py 0 → 100644
exam/templatetags/dict_access.py 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +from django import template
  2 +
  3 +from forum.models import Forum
  4 +
  5 +register = template.Library()
  6 +
  7 +"""
  8 + Template tag to load all the foruns of a post
  9 +"""
  10 +
  11 +@register.filter
  12 +def value(dictionary, key):
  13 + return dictionary[key]
exam/tests.py 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
exam/urls.py 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +from django.conf.urls import url
  2 +
  3 +from . import views
  4 +
  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 +
  9 +]
exam/views.py 0 → 100644
@@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
  1 +from django.shortcuts import render, get_object_or_404, redirect
  2 +from django.views import generic
  3 +from django.contrib.auth.decorators import login_required
  4 +from django.core.paginator import Paginator, EmptyPage
  5 +from django.contrib.auth.mixins import LoginRequiredMixin
  6 +from rolepermissions.mixins import HasRoleMixin
  7 +from django.core.urlresolvers import reverse_lazy
  8 +from django.utils.translation import ugettext_lazy as _
  9 +from rolepermissions.verifications import has_role
  10 +from rolepermissions.verifications import has_object_permission
  11 +# from django.views.generic.edit import FormMixin
  12 +
  13 +from .forms import ExamForm
  14 +from .models import Exam, Answer
  15 +from core.mixins import NotificationMixin
  16 +from users.models import User
  17 +from courses.models import Course, Topic
  18 +
  19 +class CreateExam(LoginRequiredMixin,generic.CreateView):
  20 +
  21 + login_url = reverse_lazy("core:home")
  22 + redirect_field_name = 'next'
  23 + model = Exam
  24 + form_class = PollForm
  25 + context_object_name = 'exam'
  26 + template_name = 'exam/form_exam.html'
  27 + success_url = reverse_lazy('core:home')
  28 +
  29 + 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()
  34 +
  35 + 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)
  38 + answer.save()
  39 +
  40 + return super(CreateExam, self).form_valid(form)
  41 +
  42 + def form_invalid(self, form,**kwargs):
  43 + context = super(CreateExam, self).form_invalid(form)
  44 + answers = {}
  45 + for key in self.request.POST:
  46 + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'beginDate' and key != 'endDate'):
  47 + answers[key] = self.request.POST[key]
  48 +
  49 + keys = sorted(answers)
  50 + context.context_data['answers'] = answers
  51 + context.context_data['keys'] = keys
  52 + return context
  53 +
  54 +class UpdateExam(LoginRequiredMixin,generic.UpdateView):
  55 +
  56 + login_url = reverse_lazy("core:home")
  57 + redirect_field_name = 'next'
  58 + model = Exam
  59 + form_class = ExamForm
  60 + context_object_name = 'exam'
  61 + template_name = 'poll/form_exam.html'
  62 + success_url = reverse_lazy('core:home')
  63 +
  64 + def dispatch(self, *args, **kwargs):
  65 + poll = get_object_or_404(Poll, slug = self.kwargs.get('slug'))
  66 +
  67 + if(not has_object_permission('edit_exam', self.request.user, exam)):
  68 + return self.handle_no_permission()
  69 + return super(UpdateExam, self).dispatch(*args, **kwargs)
  70 +
  71 + def get_object(self, queryset=None):
  72 + return get_object_or_404(Poll, slug = self.kwargs.get('slug'))
  73 +
  74 + def form_valid(self, form):
  75 + poll = self.object
  76 + poll = form.save(commit = False)
  77 + poll.answers.all().delete()
  78 + poll.save()
  79 +
  80 + for key in self.request.POST:
  81 + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'beginDate' and key != 'endDate'):
  82 + answer = Answer(answer=self.request.POST[key],order=key,exam=exam)
  83 + answer.save()
  84 +
  85 + return super(UpdateExam, self).form_valid(form)
  86 +
  87 + def form_invalid(self, form,**kwargs):
  88 + context = super(UpdateExam, self).form_invalid(form)
  89 + 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]
  93 +
  94 + keys = sorted(answers)
  95 + context.context_data['answers'] = answers
  96 + context.context_data['keys'] = keys
  97 + return context
forum/static/js/forum.js
@@ -255,6 +255,49 @@ function answer(id, url) { @@ -255,6 +255,49 @@ function answer(id, url) {
255 255
256 /* 256 /*
257 * 257 *
  258 +* Function to load form to edit post answer
  259 +*
  260 +*/
  261 +function edit_post_answer(url, answer_id) {
  262 + $.ajax({
  263 + url: url,
  264 + success: function(data) {
  265 + $("#answer_"+answer_id).find(".post_answer_content").hide();
  266 + $("#answer_"+answer_id).find(".post_answer_content").after(data);
  267 +
  268 + var frm = $("#answer_"+answer_id).find(".answer_post_form");
  269 + frm.submit(function () {
  270 + $.ajax({
  271 + type: frm.attr('method'),
  272 + url: frm.attr('action'),
  273 + data: frm.serialize(),
  274 + success: function (data) {
  275 + $("#answer_"+answer_id).parent().after(data);
  276 + frm.parent().parent().remove();
  277 + },
  278 + error: function(data) {
  279 + console.log(frm.serialize());
  280 + console.log('Error');
  281 + }
  282 + });
  283 + return false;
  284 + });
  285 + }
  286 + });
  287 +}
  288 +
  289 +/*
  290 +*
  291 +* Function to cancel post answer edition
  292 +*
  293 +*/
  294 +function cancelEditPostAnswer(answer_id) {
  295 + $("#answer_"+answer_id).find(".post_answer_content").show();
  296 + $("#answer_"+answer_id).find(".answer_post_form").remove();
  297 +}
  298 +
  299 +/*
  300 +*
258 * Function to delete an answer 301 * Function to delete an answer
259 * 302 *
260 */ 303 */
forum/templates/post/post_update_form.html
1 {% load i18n permission_tags list_post %} 1 {% load i18n permission_tags list_post %}
2 {% load widget_tweaks %} 2 {% load widget_tweaks %}
3 3
4 -<form class="edit_post_form" method="post" action="{% url 'forum:update_post' post.id %}" enctype="multipart/form-data"> 4 +<form class="edit_post_form" method="post" action="{% url 'course:forum:update_post' post.id %}" enctype="multipart/form-data">
5 {% csrf_token %} 5 {% csrf_token %}
6 {% for field in form %} 6 {% for field in form %}
7 {% if field.field.widget.input_type == 'hidden' %} 7 {% if field.field.widget.input_type == 'hidden' %}
forum/templates/post_answers/post_answer_form.html
1 {% load static i18n %} 1 {% load static i18n %}
2 {% load widget_tweaks %} 2 {% load widget_tweaks %}
3 3
4 -<form class="answer_post_form" method="post" action="{% if answer %}{% else %}{% url 'course:forum:reply_post' %}{% endif %}" enctype="multipart/form-data"> 4 +<form class="answer_post_form" method="post" action="{% if answer %}{% url 'course:forum:update_post_answer' answer.id %}{% else %}{% url 'course:forum:reply_post' %}{% endif %}" enctype="multipart/form-data">
5 {% csrf_token %} 5 {% csrf_token %}
6 {% for field in form %} 6 {% for field in form %}
7 {% if field.field.widget.input_type == 'hidden' %} 7 {% if field.field.widget.input_type == 'hidden' %}
@@ -27,11 +27,18 @@ @@ -27,11 +27,18 @@
27 </div> 27 </div>
28 </div> 28 </div>
29 {% endif %} 29 {% endif %}
30 - <span class="input-group-btn">  
31 - <button type="submit" class="btn btn-fab btn-fab-mini">  
32 - <i class="material-icons">send</i>  
33 - </button>  
34 - </span> 30 + {% if answer %}
  31 + <div class="pull-right">
  32 + <button type="button" onclick="cancelEditPostAnswer('{{ answer.id }}')" class="btn btn-danger btn-raised">{% trans 'Cancel' %}</button>
  33 + <button type="submit" class="btn btn-primary btn-raised">{% trans 'Save changes' %}</button>
  34 + </div>
  35 + {% else %}
  36 + <span class="input-group-btn">
  37 + <button type="submit" class="btn btn-fab btn-fab-mini">
  38 + <i class="material-icons">send</i>
  39 + </button>
  40 + </span>
  41 + {% endif %}
35 </div> 42 </div>
36 </div> 43 </div>
37 {% endif %} 44 {% endif %}
forum/templates/post_answers/post_answer_list.html
@@ -2,28 +2,36 @@ @@ -2,28 +2,36 @@
2 2
3 {% if answers|length > 0 %} 3 {% if answers|length > 0 %}
4 {% for answer in answers %} 4 {% for answer in answers %}
5 - <div id="answer_{{ answer.id }}" class="row" style="background-color: #e0e0e0">  
6 - <div class="col-sm-12 col-xs-12">  
7 - <h3 class="user-name">  
8 - {{ answer.user }}  
9 - {% if request.user|has_role:'system_admin' or request.user == answer.user %}  
10 - <div class="pull-right">  
11 - <div class="btn-group icon-more-horiz">  
12 - <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">  
13 - <i class="material-icons">more_horiz</i>  
14 - </a>  
15 - <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">  
16 - <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>  
17 - <li><a href="javascript:delete_answer('{% url 'course:forum:delete_answer' answer.id %}', '{{ answer.id }}', '{% trans "Are you sure you want to delete this answer?" %}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>  
18 - </ul> 5 + <div>
  6 + <div id="answer_{{ answer.id }}" class="row" style="background-color: #e0e0e0">
  7 + <div class="col-sm-12 col-xs-12">
  8 + <h3 class="user-name">
  9 + {{ answer.user }}
  10 + {% if request.user|has_role:'system_admin' or request.user == answer.user %}
  11 + <div class="pull-right">
  12 + <div class="btn-group icon-more-horiz">
  13 + <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  14 + <i class="material-icons">more_horiz</i>
  15 + </a>
  16 + <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  17 + <li><a href="javascript:edit_post_answer('{% url 'course:forum:update_post_answer' answer.id %}', '{{ answer.id }}')"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>
  18 + <li><a href="javascript:delete_answer('{% url 'course:forum:delete_answer' answer.id %}', '{{ answer.id }}', '{% trans "Are you sure you want to delete this answer?" %}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>
  19 + </ul>
  20 + </div>
19 </div> 21 </div>
  22 + {% endif %}
  23 + </h3>
  24 + <div class="post_answer_content">
  25 + <div class="card-data">
  26 + <p class="comment-date"><i class="fa fa-clock-o"></i> {{ answer.answer_date|timesince }} {% trans 'ago' %}
  27 + {% if answer.answer_date != answer.modifiction_date %}
  28 + <em> - {% trans 'Edited' %}</em>
  29 + {% endif %}
  30 + </p>
20 </div> 31 </div>
21 - {% endif %}  
22 - </h3>  
23 - <div class="card-data">  
24 - <p class="comment-date"><i class="fa fa-clock-o"></i> {{ answer.answer_date|timesince }} {% trans 'ago' %}</p> 32 + <p class="comment-text">{{ answer.message|linebreaks }}</p>
  33 + </div>
25 </div> 34 </div>
26 - <p class="comment-text">{{ answer.message|linebreaks }}</p>  
27 </div> 35 </div>
28 </div> 36 </div>
29 {% endfor %} 37 {% endfor %}
forum/templates/post_answers/post_answer_render.html
1 {% load i18n permission_tags %} 1 {% load i18n permission_tags %}
2 2
3 -<div id="answer_{{ answer.id }}" class="row" style="background-color: #e0e0e0">  
4 - <div class="col-sm-12 col-xs-12">  
5 - <h3 class="user-name">  
6 - {{ answer.user }}  
7 - {% if request.user|has_role:'system_admin' or request.user == answer.user %}  
8 - <div class="pull-right">  
9 - <div class="btn-group icon-more-horiz">  
10 - <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">  
11 - <i class="material-icons">more_horiz</i>  
12 - </a>  
13 - <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">  
14 - <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>  
15 - <li><a href="javascript:delete_answer('{% url 'course:forum:delete_answer' answer.id %}', '{{ answer.id }}', '{% trans "Are you sure you want to delete this answer?" %}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>  
16 - </ul> 3 +<div>
  4 + <div id="answer_{{ answer.id }}" class="row" style="background-color: #e0e0e0">
  5 + <div class="col-sm-12 col-xs-12">
  6 + <h3 class="user-name">
  7 + {{ answer.user }}
  8 + {% if request.user|has_role:'system_admin' or request.user == answer.user %}
  9 + <div class="pull-right">
  10 + <div class="btn-group icon-more-horiz">
  11 + <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  12 + <i class="material-icons">more_horiz</i>
  13 + </a>
  14 + <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  15 + <li><a href="javascript:edit_post_answer('{% url 'course:forum:update_post_answer' answer.id %}', '{{ answer.id }}')"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>
  16 + <li><a href="javascript:delete_answer('{% url 'course:forum:delete_answer' answer.id %}', '{{ answer.id }}', '{% trans "Are you sure you want to delete this answer?" %}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>
  17 + </ul>
  18 + </div>
17 </div> 19 </div>
  20 + {% endif %}
  21 + </h3>
  22 + <div class="post_answer_content">
  23 + <div class="card-data">
  24 + <p class="comment-date"><i class="fa fa-clock-o"></i> {{ answer.answer_date|timesince }} {% trans 'ago' %}
  25 + {% if answer.answer_date != answer.modifiction_date %}
  26 + <em> - {% trans 'Edited' %}</em>
  27 + {% endif %}
  28 + </p>
18 </div> 29 </div>
19 - {% endif %}  
20 - </h3>  
21 - <div class="card-data">  
22 - <p class="comment-date"><i class="fa fa-clock-o"></i> {{ answer.answer_date|timesince }} {% trans 'ago' %}</p> 30 + <p class="comment-text">{{ answer.message|linebreaks }}</p>
  31 + </div>
23 </div> 32 </div>
24 - <p class="comment-text">{{ answer.message|linebreaks }}</p>  
25 </div> 33 </div>
26 </div> 34 </div>
27 \ No newline at end of file 35 \ No newline at end of file
@@ -18,6 +18,7 @@ urlpatterns = [ @@ -18,6 +18,7 @@ urlpatterns = [
18 url(r'^post_deleted/$', views.post_deleted, name='deleted_post'), 18 url(r'^post_deleted/$', views.post_deleted, name='deleted_post'),
19 url(r'^post_answers/$', views.PostAnswerIndex.as_view(), name='post_answers'), 19 url(r'^post_answers/$', views.PostAnswerIndex.as_view(), name='post_answers'),
20 url(r'^reply_post/$', views.CreatePostAnswerView.as_view(), name='reply_post'), 20 url(r'^reply_post/$', views.CreatePostAnswerView.as_view(), name='reply_post'),
  21 + url(r'^update_post_answer/(?P<pk>[\w_-]+)/$', views.PostAnswerUpdateView.as_view(), name='update_post_answer'),
21 url(r'^render_post_answer/([\w_-]+)/$', views.render_post_answer, name='render_post_answer'), 22 url(r'^render_post_answer/([\w_-]+)/$', views.render_post_answer, name='render_post_answer'),
22 url(r'^delete_post_answer/(?P<pk>[\w_-]+)/$', views.PostAnswerDeleteView.as_view(), name='delete_answer'), 23 url(r'^delete_post_answer/(?P<pk>[\w_-]+)/$', views.PostAnswerDeleteView.as_view(), name='delete_answer'),
23 url(r'^post_answer_deleted/$', views.answer_deleted, name='deleted_answer'), 24 url(r'^post_answer_deleted/$', views.answer_deleted, name='deleted_answer'),
forum/views.py
@@ -210,6 +210,20 @@ def render_post_answer(request, answer): @@ -210,6 +210,20 @@ def render_post_answer(request, answer):
210 210
211 return render(request, "post_answers/post_answer_render.html", context) 211 return render(request, "post_answers/post_answer_render.html", context)
212 212
  213 +class PostAnswerUpdateView(LoginRequiredMixin, generic.UpdateView):
  214 + login_url = reverse_lazy("core:home")
  215 + redirect_field_name = 'next'
  216 +
  217 + form_class = PostAnswerForm
  218 + model = PostAnswer
  219 + template_name = "post_answers/post_answer_form.html"
  220 + context_object_name = 'answer'
  221 +
  222 + def get_success_url(self):
  223 + self.success_url = reverse('course:forum:render_post_answer', args = (self.object.id, ))
  224 +
  225 + return self.success_url
  226 +
213 class PostAnswerDeleteView(LoginRequiredMixin, generic.DeleteView): 227 class PostAnswerDeleteView(LoginRequiredMixin, generic.DeleteView):
214 login_url = reverse_lazy("core:home") 228 login_url = reverse_lazy("core:home")
215 redirect_field_name = 'next' 229 redirect_field_name = 'next'
links/models.py
  1 +
1 from django.db import models 2 from django.db import models
2 from courses.models import Material 3 from courses.models import Material
3 from autoslug.fields import AutoSlugField 4 from autoslug.fields import AutoSlugField
poll/templates/poll/create.html 0 → 100644
@@ -0,0 +1,206 @@ @@ -0,0 +1,206 @@
  1 +{% extends "topic/index.html" %}
  2 +
  3 +{% load i18n widget_tweaks dict_access static%}
  4 +
  5 +{% block style %}
  6 + <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  7 +{% endblock %}
  8 +
  9 +{% block content %}
  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 + {% block title_poll %}
  19 + <!-- Put your title here!!! -->
  20 + <h4 class="modal-title" id="myModalLabel">{% trans "Create a Poll" %}</h4>
  21 + {% endblock title_poll %}
  22 + </div>
  23 + <!-- Modal Body -->
  24 + <div class="modal-body">
  25 +
  26 + {% block content_poll %}
  27 + <!-- Put ONLY your content here!!! -->
  28 + <div class="conteiner">
  29 + <div class="row form-group">
  30 + <div class="col-md-1">
  31 + </br>
  32 + <label><span class="glyphicon glyphicon-hand-right"></span></label>
  33 + </div>
  34 + <div class="col-md-10">
  35 + <div class="has-success">
  36 + <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?" %}'>
  37 + <span class="help-block">{% trans "A Question to be answered" %}</span>
  38 + </div>
  39 + </div>
  40 + {% if form.name.errors %}
  41 + <div class="col-md-10 not_submited">
  42 + </br>
  43 + <div class="alert alert-danger alert-dismissible" role="alert">
  44 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  45 + <span aria-hidden="true">&times;</span>
  46 + </button>
  47 + <ul>
  48 + {% for error in form.name.errors %}
  49 + <li>{{ error }}</li>
  50 + {% endfor %}
  51 + </ul>
  52 + </div>
  53 + </div>
  54 + {% endif %}
  55 + </div>
  56 + <form id="form" class="" action="" method="post">
  57 + {% csrf_token %}
  58 + {% for key in keys %}
  59 + <div class="row form-group">
  60 + <div class="col-md-1">
  61 + </br>
  62 + <label><span class="glyphicon glyphicon-move"></span></label>
  63 + </div>
  64 + <div class="col-md-10">
  65 + <div class="has-success is-empty">
  66 + <input type="text" name="{{key}}" class="form-control" placeholder='{% trans "Answer" %}' value="{{ answers|value:key }}">
  67 + <span class="help-block">{% trans "Possible answer for the question" %}</span>
  68 + </div>
  69 + </div>
  70 + <div class="col-md-1">
  71 + </br>
  72 + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>
  73 + </div>
  74 + </div>
  75 + {% empty %}
  76 + <div class="row form-group">
  77 + <div class="col-md-1">
  78 + </br>
  79 + <label><span class="glyphicon glyphicon-move"></span></label>
  80 + </div>
  81 + <div class="col-md-10">
  82 + <div class="has-success is-empty">
  83 + <input type="text" name="1" class="form-control" placeholder='{% trans "Answer" %}'>
  84 + <span class="help-block">{% trans "Possible answer for the question" %}</span>
  85 + </div>
  86 + </div>
  87 + <div class="col-md-1">
  88 + </br>
  89 + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>
  90 + </div>
  91 + </div>
  92 + {% endfor %}
  93 + </form>
  94 + </br>
  95 + </div>
  96 + <button type="button" id="add" class="btn btn-primary btn-block btn-sm">add</button>
  97 + <div class="row form-group">
  98 + <label for="{{ form.limit_date.auto_id }}">{{ form.limit_date.label }}</label>
  99 + {% render_field form.limit_date class="form-control" form="form"%}
  100 + {# <input form="form" class="form-control" type="date" name="{{form.limit_date.name}}" {% if form.limit_date.value != None %}value="{% if form.limit_date.value.year %}{{form.limit_date.value|date:'Y-m-d'}}{% else %}{{form.limit_date.value}}{% endif %}"{% endif %}>#}
  101 + {% if form.limit_date.errors %}
  102 + <div class="not_submited">
  103 + </br>
  104 + <div class="alert alert-danger alert-dismissible" role="alert">
  105 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  106 + <span aria-hidden="true">&times;</span>
  107 + </button>
  108 + <ul>
  109 + {% for error in form.limit_date.errors %}
  110 + <li>{{ error }}</li>
  111 + {% endfor %}
  112 + </ul>
  113 + </div>
  114 + </div>
  115 + {% endif %}
  116 + </div>
  117 +
  118 + <div class="row form-group">
  119 + <label for="{{ form.students.auto_id }}">{{ form.students.label }}</label>
  120 + {% render_field form.students class="form-control" form="form"%}
  121 + </div>
  122 + <div class="row form-group">
  123 + <div class="checkbox">
  124 + <label>
  125 + {% render_field form.all_students class="form-control" form="form" %}<span class="checkbox-material"><span class="check"></span></span> {{form.all_students.label }}
  126 + </label>
  127 + </div>
  128 + {% if form.all_students.errors %}
  129 + <div class="not_submited">
  130 + </br>
  131 + <div class="alert alert-danger alert-dismissible" role="alert">
  132 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  133 + <span aria-hidden="true">&times;</span>
  134 + </button>
  135 + <ul>
  136 + {% for error in form.all_students.errors %}
  137 + <li>{{ error }}</li>
  138 + {% endfor %}
  139 + </ul>
  140 + </div>
  141 + </div>
  142 + {% endif %}
  143 + </div>
  144 +
  145 + {% endblock content_poll %}
  146 + </div>
  147 +
  148 + <!-- Modal Footer -->
  149 + <div class="modal-footer">
  150 +
  151 + <!-- Don't remove that!!! -->
  152 + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  153 + {% block button_save %}
  154 + <!-- Put curtom buttons here!!! -->
  155 + <button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Create" %}</button>
  156 + {% endblock button_save %}
  157 + </div>
  158 +
  159 + </div>
  160 + </div>
  161 +</div>
  162 +<script type="text/javascript">
  163 +// Este js tem que ficar aqui se não a tag "trans" não vai funcionar
  164 +$(window).ready(function() { // utilizado para abrir o modal quando tiver tido algum erro no preenchimento do formulario
  165 + if($('.not_submited').length){
  166 + $('#poll').modal('show');
  167 + }
  168 +});
  169 +$( "#form" ).sortable({ // utilizado para fazer a re-organização das respostas
  170 + delay: 100,
  171 + distance: 5,
  172 + update: function( event, ui ) {
  173 + var cont = 1;
  174 + $("#form div div div input").each(function(){
  175 + $(this).attr('name',cont++);
  176 + });
  177 + },
  178 +});
  179 +name = 2;
  180 +$("#add").click(function() { // utilizado para adicionar um novo campo de resposta
  181 + //Obs: não funcionar se estiver importado no head, só funciona se estiver no final do arquivo
  182 + $("#form").append('\
  183 + <div class="row form-group">\
  184 + <div class="col-md-1">\
  185 + </br>\
  186 + <label><span class="glyphicon glyphicon-move"></span></label>\
  187 + </div>\
  188 + <div class="col-md-10">\
  189 + <div class="has-success is-empty">\
  190 + <input type="text" name="1" class="form-control" placeholder="{% trans "Answer" %}">\
  191 + <span class="help-block">{% trans "Possible answer for the question" %}</span>\
  192 + </div>\
  193 + </div>\
  194 + <div class="col-md-1">\
  195 + </br>\
  196 + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>\
  197 + </div>\
  198 + </div>');
  199 + var cont = 1;
  200 + $("#form div div div input").each(function(){
  201 + $(this).attr('name',cont++);
  202 + });
  203 +});
  204 +</script>
  205 +<a href="" data-toggle="modal" data-target="#poll">modal</a>
  206 +{% endblock content %}
poll/templates/poll/create_update.html
@@ -1,206 +0,0 @@ @@ -1,206 +0,0 @@
1 -{% extends "topic/index.html" %}  
2 -  
3 -{% load i18n widget_tweaks dict_access static%}  
4 -  
5 -{% block style %}  
6 - <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>  
7 -{% endblock %}  
8 -  
9 -{% block content %}  
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 -  
21 - </div>  
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">&times;</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 - <label for="{{ form.limit_date.auto_id }}">{{ form.limit_date.label }}</label>  
97 - {% render_field form.limit_date class="form-control" form="form"%}  
98 - {# <input form="form" class="form-control" type="date" name="{{form.limit_date.name}}" {% if form.limit_date.value != None %}value="{% if form.limit_date.value.year %}{{form.limit_date.value|date:'Y-m-d'}}{% else %}{{form.limit_date.value}}{% endif %}"{% endif %}>#}  
99 - {% if form.limit_date.errors %}  
100 - <div class="not_submited">  
101 - </br>  
102 - <div class="alert alert-danger alert-dismissible" role="alert">  
103 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
104 - <span aria-hidden="true">&times;</span>  
105 - </button>  
106 - <ul>  
107 - {% for error in form.limit_date.errors %}  
108 - <li>{{ error }}</li>  
109 - {% endfor %}  
110 - </ul>  
111 - </div>  
112 - </div>  
113 - {% endif %}  
114 - </div>  
115 -  
116 - <div class="row form-group">  
117 - <label for="{{ form.students.auto_id }}">{{ form.students.label }}</label>  
118 - {% render_field form.students class="form-control" form="form"%}  
119 - </div>  
120 - <div class="row form-group">  
121 - <div class="checkbox">  
122 - <label>  
123 - {% render_field form.all_students class="form-control" form="form" %}<span class="checkbox-material"><span class="check"></span></span> {{form.all_students.label }}  
124 - {# <input form="form" type="checkbox" name="{{form.all_students.name}}"><span class="checkbox-material"><span class="check"></span></span> {{ form.all_students.label }}#}  
125 - </label>  
126 - </div>  
127 - {% if form.all_students.errors %}  
128 - <div class="not_submited">  
129 - </br>  
130 - <div class="alert alert-danger alert-dismissible" role="alert">  
131 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
132 - <span aria-hidden="true">&times;</span>  
133 - </button>  
134 - <ul>  
135 - {% for error in form.all_students.errors %}  
136 - <li>{{ error }}</li>  
137 - {% endfor %}  
138 - </ul>  
139 - </div>  
140 - </div>  
141 - {% endif %}  
142 -  
143 - {# <label for="{{ form.all_students.auto_id }}">{{ form.all_students.label }}</label>#}  
144 - {# {% render_field form.all_students class="form-control" form="form"%}#}  
145 - </div>  
146 -  
147 - </div>  
148 -  
149 - <!-- Modal Footer -->  
150 - <div class="modal-footer">  
151 -  
152 - <!-- Don't remove that!!! -->  
153 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button>  
154 -  
155 - <!-- Put curtom buttons here!!! -->  
156 - <button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Create" %}</button>  
157 - </div>  
158 -  
159 - </div>  
160 - </div>  
161 -</div>  
162 -<script type="text/javascript">  
163 -// Este js tem que ficar aqui se não a tag "trans" não vai funcionar  
164 -$(window).ready(function() { // utilizado para abrir o modal quando tiver tido algum erro no preenchimento do formulario  
165 - if($('.not_submited').length){  
166 - $('#poll').modal('show');  
167 - }  
168 -});  
169 -$( "#form" ).sortable({ // utilizado para fazer a re-organização das respostas  
170 - delay: 100,  
171 - distance: 5,  
172 - update: function( event, ui ) {  
173 - var cont = 1;  
174 - $("#form div div div input").each(function(){  
175 - $(this).attr('name',cont++);  
176 - });  
177 - },  
178 -});  
179 -name = 2;  
180 -$("#add").click(function() { // utilizado para adicionar um novo campo de resposta  
181 - //Obs: não funcionar se estiver importado no head, só funciona se estiver no final do arquivo  
182 - $("#form").append('\  
183 - <div class="row form-group">\  
184 - <div class="col-md-1">\  
185 - </br>\  
186 - <label><span class="glyphicon glyphicon-move"></span></label>\  
187 - </div>\  
188 - <div class="col-md-10">\  
189 - <div class="has-success is-empty">\  
190 - <input type="text" name="1" class="form-control" placeholder="{% trans "Answer" %}">\  
191 - <span class="help-block">{% trans "Possible answer for the question" %}</span>\  
192 - </div>\  
193 - </div>\  
194 - <div class="col-md-1">\  
195 - </br>\  
196 - <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>\  
197 - </div>\  
198 - </div>');  
199 - var cont = 1;  
200 - $("#form div div div input").each(function(){  
201 - $(this).attr('name',cont++);  
202 - });  
203 -});  
204 -</script>  
205 -<a href="" data-toggle="modal" data-target="#poll">modal</a>  
206 -{% endblock content %}  
poll/templates/poll/remove.html 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +{% extends "poll/create.html" %}
  2 +
  3 +{% load i18n %}
  4 +
  5 +{% block title_poll %}
  6 +<!-- Put your title here!!! -->
  7 +<h4 class="modal-title" id="myModalLabel">{% trans "Delete Poll" %}</h4>
  8 +{% endblock title_poll %}
  9 +
  10 +{% block content_poll %}
  11 +<!-- Put ONLY your content here!!! -->
  12 +<form action="" method="post">
  13 + {% csrf_token %}
  14 + <h2>{% trans 'Are you sure you want to delete the subject' %} "{{poll}}"?</h2>
  15 + <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" />
  16 + <a href="" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a>
  17 +</form>
  18 +{% endblock content_poll %}
  19 +
  20 +{% block button_save %}
  21 +{% endblock button_save %}
poll/templates/poll/update.html 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +{% extends "poll/create.html" %}
  2 +
  3 +{% load i18n dict_access static%}
  4 +
  5 +{% block title_poll %}
  6 +<!-- Put your title here!!! -->
  7 +<h4 class="modal-title" id="myModalLabel">{% trans "Update a Poll" %}</h4>
  8 +{% endblock title_poll %}
  9 +
  10 +{% block button_save %}
  11 +<!-- Put curtom buttons here!!! -->
  12 +<button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Update" %}</button>
  13 +{% endblock button_save %}
@@ -5,5 +5,8 @@ from . import views @@ -5,5 +5,8 @@ from . import views
5 urlpatterns = [ 5 urlpatterns = [
6 url(r'^create/(?P<slug>[\w\-_]+)/$', views.CreatePoll.as_view(), name='create_poll'), # topic slug 6 url(r'^create/(?P<slug>[\w\-_]+)/$', views.CreatePoll.as_view(), name='create_poll'), # topic slug
7 url(r'^update/(?P<slug>[\w\-_]+)/$', views.UpdatePoll.as_view(), name='update_poll'), # poll slug 7 url(r'^update/(?P<slug>[\w\-_]+)/$', views.UpdatePoll.as_view(), name='update_poll'), # poll slug
  8 + url(r'^teste/(?P<slug>[\w\-_]+)/$', views.CreatePollModal.as_view(), name='teste'), # poll
  9 + url(r'^mymodal/', views.MyModal.as_view(), name='mymodal'),
  10 + url(r'^delete/(?P<slug>[\w\-_]+)/$', views.DeletePoll.as_view(), name='delete_poll'), # poll
8 11
9 ] 12 ]
@@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse_lazy @@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse_lazy
8 from django.utils.translation import ugettext_lazy as _ 8 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.views.generic.edit import FormMixin 12 # from django.views.generic.edit import FormMixin
12 13
13 from .forms import PollForm 14 from .forms import PollForm
@@ -23,7 +24,7 @@ class CreatePoll(LoginRequiredMixin,generic.CreateView): @@ -23,7 +24,7 @@ class CreatePoll(LoginRequiredMixin,generic.CreateView):
23 model = Poll 24 model = Poll
24 form_class = PollForm 25 form_class = PollForm
25 context_object_name = 'poll' 26 context_object_name = 'poll'
26 - template_name = 'poll/create_update.html' 27 + template_name = 'poll/create.html'
27 success_url = reverse_lazy('core:home') 28 success_url = reverse_lazy('core:home')
28 29
29 def form_invalid(self, form,**kwargs): 30 def form_invalid(self, form,**kwargs):
@@ -66,7 +67,7 @@ class UpdatePoll(LoginRequiredMixin,generic.UpdateView): @@ -66,7 +67,7 @@ class UpdatePoll(LoginRequiredMixin,generic.UpdateView):
66 model = Poll 67 model = Poll
67 form_class = PollForm 68 form_class = PollForm
68 context_object_name = 'poll' 69 context_object_name = 'poll'
69 - template_name = 'poll/create_update.html' 70 + template_name = 'poll/update.html'
70 success_url = reverse_lazy('core:home') 71 success_url = reverse_lazy('core:home')
71 72
72 def dispatch(self, *args, **kwargs): 73 def dispatch(self, *args, **kwargs):
@@ -121,3 +122,98 @@ class UpdatePoll(LoginRequiredMixin,generic.UpdateView): @@ -121,3 +122,98 @@ class UpdatePoll(LoginRequiredMixin,generic.UpdateView):
121 context['keys'] = keys 122 context['keys'] = keys
122 123
123 return context 124 return context
  125 +
  126 +class DeletePoll(LoginRequiredMixin, generic.DeleteView):
  127 +
  128 + allowed_roles = ['professor', 'system_admin']
  129 + login_url = reverse_lazy("core:home")
  130 + redirect_field_name = 'next'
  131 + model = Poll
  132 + template_name = 'poll/remove.html'
  133 +
  134 + # def dispatch(self, *args, **kwargs):
  135 + # poll = get_object_or_404(Poll, slug = self.kwargs.get('slug'))
  136 + # if(not has_object_permission('delete_subject', self.request.user, subject)):
  137 + # return self.handle_no_permission()
  138 + # return super(DeleteSubjectView, self).dispatch(*args, **kwargs)
  139 +
  140 +
  141 + def get_context_data(self, **kwargs):
  142 + context = super(DeletePoll, self).get_context_data(**kwargs)
  143 + context['course'] = self.object.topic.subject.course
  144 + context['subject'] = self.object.topic.subject
  145 + context['poll'] = self.object
  146 + context['subjects'] = self.object.topic.subject.course.subjects.filter(Q(visible=True) | Q(professors__in=[self.request.user]))
  147 + if (has_role(self.request.user,'system_admin')):
  148 + context['subjects'] = self.object.topic.subject.course.subjects.all()
  149 + return context
  150 +
  151 + def get_success_url(self):
  152 + return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug})
  153 +
  154 +
  155 +from django_modalview.generic.edit import ModalCreateView
  156 +from django_modalview.generic.component import ModalResponse
  157 +
  158 +class CreatePollModal(LoginRequiredMixin,ModalCreateView):
  159 +
  160 + login_url = reverse_lazy("core:home")
  161 + redirect_field_name = 'next'
  162 + model = Poll
  163 + form_class = PollForm
  164 + context_object_name = 'poll'
  165 + template_name = 'poll/create.html'
  166 + success_url = reverse_lazy('core:home')
  167 +
  168 + def form_invalid(self, form,**kwargs):
  169 + context = super(CreatePollModal, self).form_invalid(form)
  170 + answers = {}
  171 + for key in self.request.POST:
  172 + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date' and key != 'all_students' and key != 'students'):
  173 + answers[key] = self.request.POST[key]
  174 +
  175 + keys = sorted(answers)
  176 + context.context_data['answers'] = answers
  177 + context.context_data['keys'] = keys
  178 + return context
  179 +
  180 + def form_valid(self, form):
  181 + self.object = form.save(commit = False)
  182 + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  183 + self.object.topic = topic
  184 + self.object.save()
  185 +
  186 + for key in self.request.POST:
  187 + if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date' and key != 'all_students' and key != 'students'):
  188 + answer = Answer(answer=self.request.POST[key],order=key,poll=self.object)
  189 + answer.save()
  190 +
  191 + return super(CreatePollModal, self).form_valid(form)
  192 +
  193 + def get_context_data(self, **kwargs):
  194 + context = super(CreatePollModal, self).get_context_data(**kwargs)
  195 + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  196 + context['course'] = topic.subject.course
  197 + context['subject'] = topic.subject
  198 + context['subjects'] = topic.subject.course.subjects.all()
  199 + return context
  200 +
  201 +
  202 +from django_modalview.generic.base import ModalTemplateView
  203 +
  204 +class MyModal(ModalTemplateView):
  205 + '''
  206 + This modal inherit of ModalTemplateView, so it just display a text without logic.
  207 + '''
  208 + def __init__(self, *args, **kwargs):
  209 + '''
  210 + You have to call the init method of the parent, before to overide the values:
  211 + - title: The title display in the modal-header
  212 + - icon: The css class that define the modal's icon
  213 + - description: The content of the modal.
  214 + - close_button: A button object that has several attributes.(explain below)
  215 + '''
  216 + super(MyModal, self).__init__(*args, **kwargs)
  217 + self.title = "My modal"
  218 + self.description = "This is my description"
  219 + self.icon = "icon-mymodal"
users/templates/list_users.html
@@ -51,9 +51,13 @@ @@ -51,9 +51,13 @@
51 <div class="panel-body"> 51 <div class="panel-body">
52 <div class="col-md-4"> 52 <div class="col-md-4">
53 {% if acc.image %} 53 {% if acc.image %}
54 - <img src="{{ acc.image.url }}" alt="photoUser" class="img-circle img-responsive"> 54 + <img src="{{ acc.image.url }}" alt="photoUser" class="img-circle img-responsive img-list-user">
55 {% else %} 55 {% else %}
56 - <img src="{% static 'images/avatar.png' %}" alt="Avatar" class="img-circle img-responsive"> 56 + {% if acc.gender == 'M' %}
  57 + <img src="{% static 'img/male_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user">
  58 + {% else %}
  59 + <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user">
  60 + {% endif %}
57 {% endif %} 61 {% endif %}
58 </div> 62 </div>
59 <div class="col-md-8"> 63 <div class="col-md-8">
users/templates/users/profile.html
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 <ul class="nav nav-pills nav-stacked"> 20 <ul class="nav nav-pills nav-stacked">
21 <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> 21 <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
22 <li><a href="{% url 'users:profile' %}">{% trans 'View Profile' %}</a></li> 22 <li><a href="{% url 'users:profile' %}">{% trans 'View Profile' %}</a></li>
23 - <li><a href="{% url 'users:edit_profile' user.id %}">{% trans 'Edit Profile' %}</a></li> 23 + <li><a href="{% url 'users:update_profile' %}">{% trans 'Edit Profile' %}</a></li>
24 </ul> 24 </ul>
25 </div> 25 </div>
26 </div> 26 </div>
@@ -9,7 +9,6 @@ urlpatterns = [ @@ -9,7 +9,6 @@ urlpatterns = [
9 url(r'^view/(?P<username>[\w_-]+)/$', views.View.as_view(), name='view'), 9 url(r'^view/(?P<username>[\w_-]+)/$', views.View.as_view(), name='view'),
10 url(r'^delete/(?P<username>[\w_-]+)/$', views.delete, name='delete'), 10 url(r'^delete/(?P<username>[\w_-]+)/$', views.delete, name='delete'),
11 url(r'^profile/$', views.Profile.as_view(), name='profile'), 11 url(r'^profile/$', views.Profile.as_view(), name='profile'),
12 - url(r'^profile/editar/(?P<username>[\w_-]+)/$', views.EditProfile.as_view(), name='edit_profile'),  
13 # 12 #
14 url(r'^profile/update/$', views.UpdateProfile.as_view(), name='update_profile'), 13 url(r'^profile/update/$', views.UpdateProfile.as_view(), name='update_profile'),
15 url(r'^profile/delete/$', views.DeleteUser.as_view(), name='delete_profile'), 14 url(r'^profile/delete/$', views.DeleteUser.as_view(), name='delete_profile'),
users/views.py
@@ -142,32 +142,4 @@ class Profile(LoginRequiredMixin, generic.DetailView): @@ -142,32 +142,4 @@ class Profile(LoginRequiredMixin, generic.DetailView):
142 142
143 def get_object(self): 143 def get_object(self):
144 user = get_object_or_404(User, username = self.request.user.username) 144 user = get_object_or_404(User, username = self.request.user.username)
145 - return user  
146 -  
147 -class EditProfile(LoginRequiredMixin, generic.UpdateView):  
148 -  
149 - login_url = reverse_lazy('core:home')  
150 - redirect_field_name = 'next'  
151 - template_name = 'users/edit_profile.html'  
152 - form_class = UserForm  
153 - success_url = reverse_lazy('app:users:edit_profile')  
154 -  
155 - def get_object(self):  
156 - user = get_object_or_404(User, username = self.request.user.username)  
157 - return user  
158 -  
159 - def form_valid(self, form):  
160 - self.object = form.save(commit = False)  
161 -  
162 - if self.object.type_profile == 2:  
163 - assign_role(self.object, 'student')  
164 - elif self.object.type_profile == 1:  
165 - assign_role(self.object, 'professor')  
166 - elif self.object.is_staff:  
167 - assign_role(self.object, 'system_admin')  
168 -  
169 - self.object.save()  
170 -  
171 - messages.success(self.request, _('Profile edited successfully!'))  
172 -  
173 - return super(EditProfile, self).form_valid(form)  
174 \ No newline at end of file 145 \ No newline at end of file
  146 + return user
175 \ No newline at end of file 147 \ No newline at end of file