Commit 2c886a7e73484e4896856c8e59bcc09ae8ca4fe6

Authored by ailsoncgt
2 parents a972f8d4 f3811ccd

Merge

Showing 59 changed files with 1036 additions and 848 deletions   Show diff stats
amadeus/urls.py
@@ -23,6 +23,7 @@ urlpatterns = [ @@ -23,6 +23,7 @@ urlpatterns = [
23 url(r'^home/', include('app.urls', namespace = 'app')), 23 url(r'^home/', include('app.urls', namespace = 'app')),
24 url(r'^courses/', include('courses.urls', namespace = 'course')), 24 url(r'^courses/', include('courses.urls', namespace = 'course')),
25 url(r'^users/', include('users.urls', namespace = 'users')), 25 url(r'^users/', include('users.urls', namespace = 'users')),
  26 + url(r'^exercise/', include('exercise.urls', namespace = 'exercise')),
26 url(r'^admin/', admin.site.urls), 27 url(r'^admin/', admin.site.urls),
27 url(r'^', include('core.urls', namespace = 'core')), 28 url(r'^', include('core.urls', namespace = 'core')),
28 #API 29 #API
app/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.db import migrations, models 5 from django.db import migrations, models
app/templates/home.html
@@ -96,8 +96,26 @@ @@ -96,8 +96,26 @@
96 96
97 {% endblock %} 97 {% endblock %}
98 {% if user|has_role:'system_admin' %} 98 {% if user|has_role:'system_admin' %}
99 - <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>  
100 - <li> <a href="{% url 'app:settings' %}">{% trans 'Settings' %}</a></li> 99 +
  100 + <li>
  101 + <a href="#menu_users" class="accordion" data-toggle="collapse">{% trans 'Users' %}<span class="pull-right glyphicon glyphicon-chevron-down"></span></a>
  102 + <div id="menu_users" class="collapse">
  103 + <ul class="nav nav-pill nav-stacked accordion_list">
  104 + <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>
  105 + <li> <a href="{% url 'users:create' %}">{% trans 'Create User' %}</a></li>
  106 + </ul>
  107 + </div>
  108 + </li>
  109 + <li>
  110 + <a href="#menu_settings" class="accordion" data-toggle="collapse">{% trans 'Settings' %}<span class="pull-right glyphicon glyphicon-chevron-down"></span></a>
  111 + <div id="menu_settings" class="collapse">
  112 + <ul class="nav nav-pill nav-stacked accordion_list">
  113 + <li> <a href="{% url 'app:settings' %}">{% trans "System" %}</a></li>
  114 + <li> <a href="{% url 'app:settings' %}">{% trans "Mail Sender" %}</a></li>
  115 + <li> <a href="{% url 'app:settings' %}">{% trans "Security" %}</a></li>
  116 + </ul>
  117 + </div>
  118 + </li>
101 {% endif %} 119 {% endif %}
102 </ul> 120 </ul>
103 </div> 121 </div>
core/locale/pt_BR/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid &quot;&quot; @@ -8,7 +8,7 @@ msgid &quot;&quot;
8 msgstr "" 8 msgstr ""
9 "Project-Id-Version: PACKAGE VERSION\n" 9 "Project-Id-Version: PACKAGE VERSION\n"
10 "Report-Msgid-Bugs-To: \n" 10 "Report-Msgid-Bugs-To: \n"
11 -"POT-Creation-Date: 2016-11-16 11:23-0300\n" 11 +"POT-Creation-Date: 2016-11-19 10:24-0300\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n" 14 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -23,10 +23,8 @@ msgid &quot;Password&quot; @@ -23,10 +23,8 @@ msgid &quot;Password&quot;
23 msgstr "Senha" 23 msgstr "Senha"
24 24
25 #: .\forms.py:13 25 #: .\forms.py:13
26 -#, fuzzy  
27 -#| msgid "Confirm password:"  
28 msgid "Confirm Password" 26 msgid "Confirm Password"
29 -msgstr "Confirmação de senha:" 27 +msgstr "Confirme a senha:"
30 28
31 #: .\forms.py:27 29 #: .\forms.py:27
32 msgid "There is already a registered User with this e-mail" 30 msgid "There is already a registered User with this e-mail"
@@ -40,7 +38,7 @@ msgstr &quot;Por favor, insira uma data válida&quot; @@ -40,7 +38,7 @@ msgstr &quot;Por favor, insira uma data válida&quot;
40 #, fuzzy 38 #, fuzzy
41 #| msgid "There is already a registeres User with this CPF" 39 #| msgid "There is already a registeres User with this CPF"
42 msgid "There is already a registered User with this CPF" 40 msgid "There is already a registered User with this CPF"
43 -msgstr "Já existem usuários cadastrados com este CPF" 41 +msgstr "Já existe usuário cadastrado com este CPF"
44 42
45 #: .\forms.py:52 43 #: .\forms.py:52
46 #, python-format 44 #, python-format
@@ -138,7 +136,7 @@ msgstr &quot;Autor&quot; @@ -138,7 +136,7 @@ msgstr &quot;Autor&quot;
138 msgid "Notification" 136 msgid "Notification"
139 msgstr "Notificação" 137 msgstr "Notificação"
140 138
141 -#: .\models.py:99 .\templates\base.html:92 .\templates\guest.html:70 139 +#: .\models.py:99 .\templates\base.html:92
142 msgid "Notifications" 140 msgid "Notifications"
143 msgstr "Notificações" 141 msgstr "Notificações"
144 142
@@ -166,11 +164,11 @@ msgstr &quot;Logs&quot; @@ -166,11 +164,11 @@ msgstr &quot;Logs&quot;
166 msgid "Search Files (.pdf, others) and/or activities" 164 msgid "Search Files (.pdf, others) and/or activities"
167 msgstr "Pesquisar arquivos (.pdf, outros) e/ou atividades" 165 msgstr "Pesquisar arquivos (.pdf, outros) e/ou atividades"
168 166
169 -#: .\templates\base.html:98 .\templates\guest.html:77 167 +#: .\templates\base.html:98
170 msgid "See More" 168 msgid "See More"
171 msgstr "Ver Mais" 169 msgstr "Ver Mais"
172 170
173 -#: .\templates\base.html:105 .\templates\guest.html:83 171 +#: .\templates\base.html:105
174 msgid "messages" 172 msgid "messages"
175 msgstr "Mensagens" 173 msgstr "Mensagens"
176 174
@@ -196,14 +194,22 @@ msgstr &quot;Mudar senha&quot; @@ -196,14 +194,22 @@ msgstr &quot;Mudar senha&quot;
196 msgid "Remove account" 194 msgid "Remove account"
197 msgstr "Remover conta" 195 msgstr "Remover conta"
198 196
199 -#: .\templates\guest.html:97 197 +#: .\templates\guest.html:67 .\templates\index.html:67 .\views.py:115
  198 +msgid "Guest"
  199 +msgstr "Convidado"
  200 +
  201 +#: .\templates\guest.html:80
200 msgid "Menu" 202 msgid "Menu"
201 msgstr "Menu" 203 msgstr "Menu"
202 204
203 -#: .\templates\guest.html:101 .\templates\register_user.html:110 205 +#: .\templates\guest.html:84 .\templates\register_user.html:110
204 msgid "Register" 206 msgid "Register"
205 msgstr "Cadastrar" 207 msgstr "Cadastrar"
206 208
  209 +#: .\templates\guest.html:98
  210 +msgid "Search Courses"
  211 +msgstr "Pesquisar Cursos"
  212 +
207 #: .\templates\index.html:37 213 #: .\templates\index.html:37
208 msgid "Sign in with your account to continue" 214 msgid "Sign in with your account to continue"
209 msgstr "Faça login com sua conta para continuar" 215 msgstr "Faça login com sua conta para continuar"
@@ -220,10 +226,6 @@ msgstr &quot;Lembrar E-mail&quot; @@ -220,10 +226,6 @@ msgstr &quot;Lembrar E-mail&quot;
220 msgid "Log in" 226 msgid "Log in"
221 msgstr "Acessar" 227 msgstr "Acessar"
222 228
223 -#: .\templates\index.html:67  
224 -msgid "Guest"  
225 -msgstr "Convidado"  
226 -  
227 #: .\templates\index.html:72 229 #: .\templates\index.html:72
228 msgid "Forgot your password?" 230 msgid "Forgot your password?"
229 msgstr "Esqueceu sua senha?" 231 msgstr "Esqueceu sua senha?"
@@ -236,9 +238,11 @@ msgstr &quot;Cadastrar&quot; @@ -236,9 +238,11 @@ msgstr &quot;Cadastrar&quot;
236 msgid "User Register" 238 msgid "User Register"
237 msgstr "Cadastro de usuário" 239 msgstr "Cadastro de usuário"
238 240
  241 +#: .\templates\register_user.html:61
  242 +msgid "Choose your photo..."
  243 +msgstr ""
  244 +
239 #: .\templates\register_user.html:71 245 #: .\templates\register_user.html:71
240 -#, fuzzy  
241 -#| msgid "Chose your file ..."  
242 msgid "Choose the file ..." 246 msgid "Choose the file ..."
243 msgstr "Escolha o arquivo..." 247 msgstr "Escolha o arquivo..."
244 248
@@ -249,7 +253,7 @@ msgstr &quot;Entrar&quot; @@ -249,7 +253,7 @@ msgstr &quot;Entrar&quot;
249 253
250 #: .\templates\registration\passwor_reset_complete.html:19 254 #: .\templates\registration\passwor_reset_complete.html:19
251 msgid "Your password was reseted successful" 255 msgid "Your password was reseted successful"
252 -msgstr "" 256 +msgstr "Sua senha foi resetada com sucesso"
253 257
254 #: .\templates\registration\passwor_reset_confirm.html:19 258 #: .\templates\registration\passwor_reset_confirm.html:19
255 #: .\templates\registration\passwor_reset_done.html:18 259 #: .\templates\registration\passwor_reset_done.html:18
@@ -389,9 +393,6 @@ msgstr &quot;E-mail ou senha incorretos.&quot; @@ -389,9 +393,6 @@ msgstr &quot;E-mail ou senha incorretos.&quot;
389 #~ msgid "Manage Users" 393 #~ msgid "Manage Users"
390 #~ msgstr "Gerenciar usuários" 394 #~ msgstr "Gerenciar usuários"
391 395
392 -#~ msgid "Manage Courses"  
393 -#~ msgstr "Gerenciar cursos"  
394 -  
395 #~ msgid "Category" 396 #~ msgid "Category"
396 #~ msgstr "Categoria" 397 #~ msgstr "Categoria"
397 398
core/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 import autoslug.fields 5 import autoslug.fields
core/migrations/0002_auto_20161116_1057.py
@@ -1,50 +0,0 @@ @@ -1,50 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 13:57  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.conf import settings  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - ('core', '0001_initial'),  
16 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
17 - ]  
18 -  
19 - operations = [  
20 - migrations.AddField(  
21 - model_name='notification',  
22 - name='actor',  
23 - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notification_Performer', to=settings.AUTH_USER_MODEL, verbose_name='Performer'),  
24 - ),  
25 - migrations.AddField(  
26 - model_name='notification',  
27 - name='user',  
28 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notification_Actor', to=settings.AUTH_USER_MODEL, verbose_name='User'),  
29 - ),  
30 - migrations.AddField(  
31 - model_name='log',  
32 - name='action_resource',  
33 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action_Resource', verbose_name='Action_Resource'),  
34 - ),  
35 - migrations.AddField(  
36 - model_name='log',  
37 - name='user',  
38 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Actor'),  
39 - ),  
40 - migrations.AddField(  
41 - model_name='action_resource',  
42 - name='action',  
43 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action', verbose_name='Action_Applied'),  
44 - ),  
45 - migrations.AddField(  
46 - model_name='action_resource',  
47 - name='resource',  
48 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Resource', verbose_name='Resource'),  
49 - ),  
50 - ]  
core/migrations/0002_auto_20161117_0217.py 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-17 05:17
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + initial = True
  13 +
  14 + dependencies = [
  15 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  16 + ('core', '0001_initial'),
  17 + ]
  18 +
  19 + operations = [
  20 + migrations.AddField(
  21 + model_name='notification',
  22 + name='actor',
  23 + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notification_Performer', to=settings.AUTH_USER_MODEL, verbose_name='Performer'),
  24 + ),
  25 + migrations.AddField(
  26 + model_name='notification',
  27 + name='user',
  28 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notification_Actor', to=settings.AUTH_USER_MODEL, verbose_name='User'),
  29 + ),
  30 + migrations.AddField(
  31 + model_name='log',
  32 + name='action_resource',
  33 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action_Resource', verbose_name='Action_Resource'),
  34 + ),
  35 + migrations.AddField(
  36 + model_name='log',
  37 + name='user',
  38 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Actor'),
  39 + ),
  40 + migrations.AddField(
  41 + model_name='action_resource',
  42 + name='action',
  43 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action', verbose_name='Action_Applied'),
  44 + ),
  45 + migrations.AddField(
  46 + model_name='action_resource',
  47 + name='resource',
  48 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Resource', verbose_name='Resource'),
  49 + ),
  50 + ]
core/templates/guest.html
@@ -64,24 +64,7 @@ @@ -64,24 +64,7 @@
64 </div> 64 </div>
65 <div class="navbar-collapse collapse navbar-responsive-collapse"> 65 <div class="navbar-collapse collapse navbar-responsive-collapse">
66 <ul class="nav navbar-nav navbar-right notifications"> 66 <ul class="nav navbar-nav navbar-right notifications">
67 - <li class="" data-toggle="tooltip" data-placement="bottom" title data-original-title="notifications">  
68 - <a class="dropdown-toggle" data-toggle="dropdown"> <span id="notification-count" class="badge notification-count">{{notifications.count}}</span><i class="fa fa-bell" aria-hidden="true"></i></a>  
69 - <ul id="notification-dropdown" class="dropdown-menu">  
70 - <li class="dropdown-header">{% trans 'Notifications' %}</li>  
71 - {% include "notifications.html" %}  
72 -  
73 - <li>  
74 - <a onclick="getNotifications(5)">  
75 - <div id="notification-see-more" class="list-group-item">  
76 - <div class="row-content">  
77 - <p class="list-group-item-text">{% trans 'See More' %}</p>  
78 - </div>  
79 - </a>  
80 - </li>  
81 - </ul>  
82 - </li>  
83 - <li data-toggle="tooltip" data-placement="bottom" title data-original-title="{% trans 'messages' %}"> <a href="#"><i class="fa fa-comments" aria-hidden="true"></i></a> </li>  
84 - <li > <a class="link" href="{% url 'app:index' %}">{{ user }}</a></li> 67 + <li > <a class="link" href="{% url 'app:index' %}">{% trans 'Guest' %}</a></li>
85 <li data-toggle="tooltip" data-placement="bottom" title data-original-title="log out"> <a href="{% url 'app:index' %}"><i class="fa fa-sign-out" aria-hidden="true"></i></a></li> 68 <li data-toggle="tooltip" data-placement="bottom" title data-original-title="log out"> <a href="{% url 'app:index' %}"><i class="fa fa-sign-out" aria-hidden="true"></i></a></li>
86 </ul> 69 </ul>
87 </div> 70 </div>
@@ -107,21 +90,6 @@ @@ -107,21 +90,6 @@
107 </div> 90 </div>
108 <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"> 91 <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10 col-xl-10">
109 {% block breadcrumbs %} 92 {% block breadcrumbs %}
110 -  
111 - <div class="col-md-12">  
112 - <form id="searchform" action="{% url 'course:manage' %}" method="get" accept-charset="utf-8">  
113 - <div class="input-group">  
114 - <div class="form-group is-empty">  
115 - <input type="search" class="form-control" placeholder="Search Courses" name="q" id="searchbox"></div>  
116 - <span class="input-group-btn input-group-sm">  
117 - <button type="button" class="btn btn-fab btn-fab-mini">  
118 - <i class="material-icons">search</i>  
119 - </button>  
120 - </span>  
121 - </div>  
122 - </form>  
123 - </div>  
124 -  
125 {% endblock %} 93 {% endblock %}
126 {% block render_breadcrumbs %}{% endblock %} 94 {% block render_breadcrumbs %}{% endblock %}
127 <div> 95 <div>
@@ -137,7 +105,7 @@ @@ -137,7 +105,7 @@
137 <h4 class="panel-title"> 105 <h4 class="panel-title">
138 <a class="category-course-link" data-toggle="collapse" href="#{{category.slug}}">{{category.name}}</a> 106 <a class="category-course-link" data-toggle="collapse" href="#{{category.slug}}">{{category.name}}</a>
139 </h4> 107 </h4>
140 - 108 +
141 </div> 109 </div>
142 <div id="{{category.slug}}" class="panel-collapse collapse"> 110 <div id="{{category.slug}}" class="panel-collapse collapse">
143 {% for course in category.course_category.all %} 111 {% for course in category.course_category.all %}
@@ -150,6 +118,27 @@ @@ -150,6 +118,27 @@
150 </div> 118 </div>
151 {% endfor %} 119 {% endfor %}
152 </div> 120 </div>
  121 + <div class="col-md-12">
  122 + <nav aria-label="Page navigation">
  123 + <ul class="pagination">
  124 + {% if page_obj.has_previous %}
  125 + <li>
  126 + <a href="?page={{ page_obj.previous_page_number }}"><span><<</span></a>
  127 + </li>
  128 + {% endif %}
  129 + {% for page_number in paginator.page_range %}
  130 + <li{% if page_obj.number == page_number %} class="active"{% endif %}>
  131 + <a href="?page={{ page_number }}">{{ page_number }}</a>
  132 + </li>
  133 + {% endfor %}
  134 + {% if page_obj.has_next %}
  135 + <li>
  136 + <a href="?page={{ page_obj.next_page_number }}"><span>>></span></a>
  137 + </li>
  138 + {% endif %}
  139 + </ul>
  140 + </nav>
  141 + </div>
153 {% endblock %} 142 {% endblock %}
154 </div> 143 </div>
155 </div> 144 </div>
@@ -161,4 +150,4 @@ @@ -161,4 +150,4 @@
161 {% endblock script_file %} 150 {% endblock script_file %}
162 </body> 151 </body>
163 152
164 -</html>  
165 \ No newline at end of file 153 \ No newline at end of file
  154 +</html>
core/templates/register_user.html
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
58 {% elif field.auto_id == 'id_image' %} 58 {% elif field.auto_id == 'id_image' %}
59 {% render_field field class='form-control' %} 59 {% render_field field class='form-control' %}
60 <div class="input-group"> 60 <div class="input-group">
61 - <input type="text" readonly="" class="form-control" placeholder="Choose your photo..."> 61 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">
62 <span class="input-group-btn input-group-sm"> 62 <span class="input-group-btn input-group-sm">
63 <button type="button" class="btn btn-fab btn-fab-mini"> 63 <button type="button" class="btn btn-fab btn-fab-mini">
64 <i class="material-icons">image</i> 64 <i class="material-icons">image</i>
@@ -14,6 +14,8 @@ from core.mixins import NotificationMixin @@ -14,6 +14,8 @@ from core.mixins import NotificationMixin
14 from .models import Notification, Log 14 from .models import Notification, Log
15 from rolepermissions.shortcuts import assign_role 15 from rolepermissions.shortcuts import assign_role
16 from django.contrib.auth.decorators import login_required 16 from django.contrib.auth.decorators import login_required
  17 +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
  18 +
17 #API REST IMPORTS 19 #API REST IMPORTS
18 from .serializers import LogSerializer 20 from .serializers import LogSerializer
19 from rest_framework import status, serializers, permissions, viewsets 21 from rest_framework import status, serializers, permissions, viewsets
@@ -103,15 +105,24 @@ class GuestView (ListView): @@ -103,15 +105,24 @@ class GuestView (ListView):
103 105
104 template_name = 'guest.html' 106 template_name = 'guest.html'
105 context_object_name = 'courses' 107 context_object_name = 'courses'
  108 + queryset = CourseCategory.objects.all()
106 paginate_by = 10 109 paginate_by = 10
107 110
108 - def get_queryset(self):  
109 - return Course.objects.filter(public=True)  
110 -  
111 -  
112 def get_context_data (self, **kwargs): 111 def get_context_data (self, **kwargs):
113 context = super(GuestView, self).get_context_data(**kwargs) 112 context = super(GuestView, self).get_context_data(**kwargs)
114 - context['categorys_courses'] = CourseCategory.objects.all() 113 + context['title'] = _("Guest")
  114 + queryset_list = CourseCategory.objects.all()
  115 +
  116 + paginator = Paginator(queryset_list, 10)
  117 + page = self.request.GET.get('page')
  118 + try:
  119 + queryset_list = paginator.page(page)
  120 + except PageNotAnInteger:
  121 + queryset_list = paginator.page(1)
  122 + except EmptyPage:
  123 + queryset_list = paginator.page(paginator.num_pages)
  124 +
  125 + context['categorys_courses'] = queryset_list
115 return context 126 return context
116 127
117 128
courses/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 import autoslug.fields 5 import autoslug.fields
@@ -69,8 +69,8 @@ class Migration(migrations.Migration): @@ -69,8 +69,8 @@ class Migration(migrations.Migration):
69 ], 69 ],
70 options={ 70 options={
71 'verbose_name_plural': 'Courses', 71 'verbose_name_plural': 'Courses',
72 - 'ordering': ('create_date', 'name'),  
73 'verbose_name': 'Course', 72 'verbose_name': 'Course',
  73 + 'ordering': ('create_date', 'name'),
74 }, 74 },
75 ), 75 ),
76 migrations.CreateModel( 76 migrations.CreateModel(
@@ -128,8 +128,8 @@ class Migration(migrations.Migration): @@ -128,8 +128,8 @@ class Migration(migrations.Migration):
128 ], 128 ],
129 options={ 129 options={
130 'verbose_name_plural': 'Subjects', 130 'verbose_name_plural': 'Subjects',
131 - 'ordering': ('create_date', 'name'),  
132 'verbose_name': 'Subject', 131 'verbose_name': 'Subject',
  132 + 'ordering': ('create_date', 'name'),
133 }, 133 },
134 ), 134 ),
135 migrations.CreateModel( 135 migrations.CreateModel(
@@ -160,8 +160,8 @@ class Migration(migrations.Migration): @@ -160,8 +160,8 @@ class Migration(migrations.Migration):
160 ], 160 ],
161 options={ 161 options={
162 'verbose_name_plural': 'Topics', 162 'verbose_name_plural': 'Topics',
163 - 'ordering': ('create_date', 'name'),  
164 'verbose_name': 'Topic', 163 'verbose_name': 'Topic',
  164 + 'ordering': ('create_date', 'name'),
165 }, 165 },
166 ), 166 ),
167 ] 167 ]
courses/migrations/0002_auto_20161116_1057.py
@@ -1,85 +0,0 @@ @@ -1,85 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 13:57  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.conf import settings  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
16 - ('courses', '0001_initial'),  
17 - ]  
18 -  
19 - operations = [  
20 - migrations.AddField(  
21 - model_name='subject',  
22 - name='professors',  
23 - field=models.ManyToManyField(related_name='professors_subjects', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),  
24 - ),  
25 - migrations.AddField(  
26 - model_name='subject',  
27 - name='students',  
28 - field=models.ManyToManyField(blank=True, related_name='subject_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),  
29 - ),  
30 - migrations.AddField(  
31 - model_name='material',  
32 - name='students',  
33 - field=models.ManyToManyField(related_name='materials', to=settings.AUTH_USER_MODEL, verbose_name='Students'),  
34 - ),  
35 - migrations.AddField(  
36 - model_name='material',  
37 - name='topic',  
38 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materials', to='courses.Topic', verbose_name='Topic'),  
39 - ),  
40 - migrations.AddField(  
41 - model_name='linkmaterial',  
42 - name='material',  
43 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_link', to='courses.Material', verbose_name='Material'),  
44 - ),  
45 - migrations.AddField(  
46 - model_name='filematerial',  
47 - name='material',  
48 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_file', to='courses.Material', verbose_name='Material'),  
49 - ),  
50 - migrations.AddField(  
51 - model_name='course',  
52 - name='category',  
53 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_category', to='courses.CourseCategory', verbose_name='Category'),  
54 - ),  
55 - migrations.AddField(  
56 - model_name='course',  
57 - name='coordenator',  
58 - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='course_coordenator', to=settings.AUTH_USER_MODEL, verbose_name='Coordenator'),  
59 - ),  
60 - migrations.AddField(  
61 - model_name='course',  
62 - name='professors',  
63 - field=models.ManyToManyField(related_name='courses_professors', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),  
64 - ),  
65 - migrations.AddField(  
66 - model_name='course',  
67 - name='students',  
68 - field=models.ManyToManyField(blank=True, related_name='courses_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),  
69 - ),  
70 - migrations.AddField(  
71 - model_name='activityfile',  
72 - name='diet',  
73 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='files', to='courses.Activity'),  
74 - ),  
75 - migrations.AddField(  
76 - model_name='activity',  
77 - name='students',  
78 - field=models.ManyToManyField(related_name='activities', to=settings.AUTH_USER_MODEL, verbose_name='Students'),  
79 - ),  
80 - migrations.AddField(  
81 - model_name='activity',  
82 - name='topic',  
83 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='courses.Topic', verbose_name='Topic'),  
84 - ),  
85 - ]  
courses/migrations/0002_auto_20161117_0217.py 0 → 100644
@@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-17 05:17
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + initial = True
  13 +
  14 + dependencies = [
  15 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  16 + ('courses', '0001_initial'),
  17 + ]
  18 +
  19 + operations = [
  20 + migrations.AddField(
  21 + model_name='subject',
  22 + name='professors',
  23 + field=models.ManyToManyField(related_name='professors_subjects', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),
  24 + ),
  25 + migrations.AddField(
  26 + model_name='subject',
  27 + name='students',
  28 + field=models.ManyToManyField(blank=True, related_name='subject_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  29 + ),
  30 + migrations.AddField(
  31 + model_name='material',
  32 + name='students',
  33 + field=models.ManyToManyField(related_name='materials', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  34 + ),
  35 + migrations.AddField(
  36 + model_name='material',
  37 + name='topic',
  38 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materials', to='courses.Topic', verbose_name='Topic'),
  39 + ),
  40 + migrations.AddField(
  41 + model_name='linkmaterial',
  42 + name='material',
  43 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_link', to='courses.Material', verbose_name='Material'),
  44 + ),
  45 + migrations.AddField(
  46 + model_name='filematerial',
  47 + name='material',
  48 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_file', to='courses.Material', verbose_name='Material'),
  49 + ),
  50 + migrations.AddField(
  51 + model_name='course',
  52 + name='category',
  53 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_category', to='courses.CourseCategory', verbose_name='Category'),
  54 + ),
  55 + migrations.AddField(
  56 + model_name='course',
  57 + name='coordenator',
  58 + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='course_coordenator', to=settings.AUTH_USER_MODEL, verbose_name='Coordenator'),
  59 + ),
  60 + migrations.AddField(
  61 + model_name='course',
  62 + name='professors',
  63 + field=models.ManyToManyField(related_name='courses_professors', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),
  64 + ),
  65 + migrations.AddField(
  66 + model_name='course',
  67 + name='students',
  68 + field=models.ManyToManyField(blank=True, related_name='courses_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  69 + ),
  70 + migrations.AddField(
  71 + model_name='activityfile',
  72 + name='diet',
  73 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='files', to='courses.Activity'),
  74 + ),
  75 + migrations.AddField(
  76 + model_name='activity',
  77 + name='students',
  78 + field=models.ManyToManyField(related_name='activities', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  79 + ),
  80 + migrations.AddField(
  81 + model_name='activity',
  82 + name='topic',
  83 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='courses.Topic', verbose_name='Topic'),
  84 + ),
  85 + ]
courses/templates/subject/form_view_student.html
@@ -63,33 +63,6 @@ @@ -63,33 +63,6 @@
63 </ul> 63 </ul>
64 </div> 64 </div>
65 </div> 65 </div>
66 - <div class="col-xs-4 col-md-4">  
67 - <div class="resource_inline">  
68 - <h4>{% trans 'Exercises' %}</h4>  
69 - </div>  
70 - <div class="resource_inline">  
71 - {# dropdown de create exercício #}  
72 - <div class="dropdown">  
73 - <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a>  
74 - <ul class="dropdown-menu" aria-labelledby="dLabel">  
75 - <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Create a Exercise' %}</a></li>  
76 - </ul>  
77 - </div>  
78 - </div>  
79 - <div class="presentation_{{exercise.slug}}">  
80 - {# exercício do tópico no modo de visualização #}  
81 - <ul>  
82 - {% list_topic_exercise request %}  
83 - </ul>  
84 - </div>  
85 - <div class="editation editation_{{exercise.slug}}">  
86 - {# exercício do tópico no modo de edição #}  
87 - <ul>  
88 - {% list_topic_exercise_edit request exercise %}  
89 - </ul>  
90 - </div>  
91 - </div>  
92 - {% include "exercise/create_exercise.html" %}  
93 </div> 66 </div>
94 {% endif %} 67 {% endif %}
95 68
courses/templates/subject/form_view_teacher.html
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 <button class="btn btn-default btn-sm caret-square"><i class="fa fa-caret-square-o-down fa-2x" aria-hidden="true"></i></button> 7 <button class="btn btn-default btn-sm caret-square"><i class="fa fa-caret-square-o-down fa-2x" aria-hidden="true"></i></button>
8 </div> 8 </div>
9 <div class="col-xs-9 col-md-9 titleTopic"> 9 <div class="col-xs-9 col-md-9 titleTopic">
10 - <a role="button"> 10 + <a href="{% url 'course:view_topic' topic.slug %}" role="button">
11 <h4>{{topic}}</h4> 11 <h4>{{topic}}</h4>
12 </a> 12 </a>
13 </div><!--column --> 13 </div><!--column -->
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 {% professor_subject topic.subject user as dropdown_topic %} 21 {% professor_subject topic.subject user as dropdown_topic %}
22 {% if dropdown_topic %} 22 {% if dropdown_topic %}
23 <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> 23 <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
24 - <li><a href="" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li> 24 + <li><a href="{% url 'course:replicate_topic' topic.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li>
25 <li><a href="javascript:show_editation('{{topic.slug}}')"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li> 25 <li><a href="javascript:show_editation('{{topic.slug}}')"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li>
26 <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeTopic"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li> 26 <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeTopic"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li>
27 </ul> 27 </ul>
@@ -123,23 +123,18 @@ @@ -123,23 +123,18 @@
123 </ul> 123 </ul>
124 </div> 124 </div>
125 </div> 125 </div>
126 - <div class="col-xs-4 col-md-4">  
127 <div class="resource_inline"> 126 <div class="resource_inline">
128 <h4>{% trans 'Exercises' %}</h4> 127 <h4>{% trans 'Exercises' %}</h4>
129 </div> 128 </div>
130 - <div class="presentation_{{exercise.slug}}">  
131 - {# exercício do tópico no modo de visualização #}  
132 - <ul>  
133 - {% list_topic_exercise request %}  
134 - </ul>  
135 - </div>  
136 - <div class="editation editation_{{exercise.slug}}">  
137 - {# exercício do tópico no modo de edição #}  
138 - <ul>  
139 - {% list_topic_exercise_edit request exercise %}  
140 - </ul> 129 + <div class="resource_inline">
  130 + {# dropdown de create exercício #}
  131 + <div class="dropdown">
  132 + <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a>
  133 + <ul class="dropdown-menu" aria-labelledby="dLabel">
  134 + <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Create a general exercise' %}</a></li>
  135 + </ul>
  136 + </div>
141 </div> 137 </div>
142 - </div>  
143 </div> 138 </div>
144 139
145 {# opções de cancelar e editar no modo de edição #} 140 {# opções de cancelar e editar no modo de edição #}
courses/templates/subject/replicate.html
@@ -2,61 +2,51 @@ @@ -2,61 +2,51 @@
2 2
3 {% load static i18n permission_tags widget_tweaks %} 3 {% load static i18n permission_tags widget_tweaks %}
4 4
5 -{% block breadcrumbs %}  
6 - <ol class="breadcrumb">  
7 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
8 - <li class="active">{% trans 'Replicate Subject' %}</li>  
9 - </ol>  
10 -{% endblock %}  
11 -  
12 {% block content %} 5 {% block content %}
13 -<div class="panel panel-default"> 6 +
  7 + <div class="panel panel-default">
14 <div class="panel-body"> 8 <div class="panel-body">
15 <form class="form-group " method="post" action=""> 9 <form class="form-group " method="post" action="">
16 {% csrf_token %} 10 {% csrf_token %}
17 11
18 <div class="form-group {% if subject.name.errors %} has-error{% endif %}"> 12 <div class="form-group {% if subject.name.errors %} has-error{% endif %}">
19 - <label for="{{ id_name }}" class="control-label label-static"> {% trans 'Name' %}</label>  
20 - <input class="form-control" id="id_name" maxlength="100" name="name" type="text" required="True" value="{{subject.name}}">  
21 - <span class="help-block">{% trans 'Subject name' %}</span> 13 + <label for="id_name" class="control-label label-static"> {% trans 'Name'%}</label>
  14 + <textarea class="form-control" id="id_name" maxlength="100" rows="1" name="name" placeholder="Name" type="text" required >{{subject.name}}</textarea>
22 15
  16 + <span class="help-block">{% trans 'Subject name'%}</span>
23 </div> 17 </div>
24 18
25 - <div class="form-group {% if subject.name.errors %} has-error{% endif %}">  
26 - <label for="{{ id_description }}" class="control-label label-static"> {% trans 'Description' %} </label>  
27 - <textarea class="form-control" id="id_description" name="description" type="text" required="">{{subject.description}}</textarea>  
28 - <span class="help-block">{% trans 'Subject Description' %}</span> 19 + <div class="form-group">
  20 + <label for="id_description" class="control-label label-static"> {% trans 'Description'%}</label>
  21 + <textarea class="form-control" id="id_description" name="description" placeholder="Description" type="text" >{{subject.description}}</textarea>
29 22
  23 + <span class="help-block">{% trans 'Subject description'%}</span>
30 </div> 24 </div>
31 25
32 - <div class="form-group {% if subject.name.errors %} has-error{% endif %}">  
33 - <label for="{{ id_init_date }}" class="control-label label-static"> {% trans 'Init date' %}</label>  
34 - <input type="text" class="form-control date-picker" name="{{field.name}}" value="{{field.value|date:'SHORT_DA E_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">  
35 - <span class="help-block">{% trans 'Subject init date' %}</span> 26 + <div class="form-group">
  27 + <label for="id_init_date" class="control-label label-static"> {% trans 'Init date'%}</label>
  28 + <input type="text" class="form-control date-picker" name="init_date" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
36 29
  30 + <span class="help-block">{% trans 'Init date'%}</span>
37 </div> 31 </div>
38 32
39 - <div class="form-group {% if subject.name.errors %} has-error{% endif %}">  
40 - <label for="{{ id_end_date }}" class="control-label label-static"> {% trans 'End date' %}</label>  
41 - <input type="text" class="form-control date-picker" name="{{field.name}}" value="{{field.value|date:'SHORT_DA E_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">  
42 - <span class="help-block">{% trans 'Subject end date' %}</span>  
43 -  
44 - </div>  
45 - <div class="form-group {% if subject.name.errors %} has-error{% endif %}">  
46 - <label for="{{ id_visible }}" class="control-label label-static"> {% trans 'Visible?' %} </label>  
47 - <input type="checkbox" class="form-control" id="id_visible" name="visible" required="true"/>  
48 - <span class="help-block">{% trans 'Is it visible?' %}</span> 33 + <div class="form-group">
  34 + <label for="id_end_date" class="control-label label-static"> {% trans 'End date'%}</label>
  35 + <input type="text" class="form-control date-picker" name="end_date" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
49 36
  37 + <span class="help-block">{% trans 'End date'%}</span>
50 </div> 38 </div>
51 39
  40 + <div class="form-group">
  41 + <label for="id_visible" class="control-label label-static"> {% trans 'Visible'%}</label>
  42 + <input class="form-control" id="id_visible" name="visible" type="checkbox"/>
52 43
  44 + <span class="help-block">{% trans 'Is it visible?'%}</span>
53 </div> 45 </div>
54 -  
55 <div class="col-lg-offset-4 col-lg-4"> 46 <div class="col-lg-offset-4 col-lg-4">
56 - <button type="submit" class="btn btn-raised btn-primary btn-lg btn-block">{% trans 'Replicate' %}</button> 47 + <button type="submite" class="btn btn-raised btn-primary btn-lg btn-block">{% trans 'Replicate' %}</button>
57 </div> 48 </div>
58 </form> 49 </form>
59 -  
60 </div> 50 </div>
61 </div> 51 </div>
62 52
@@ -70,4 +60,4 @@ @@ -70,4 +60,4 @@
70 $('#id_description').summernote({height: 300}); 60 $('#id_description').summernote({height: 300});
71 }); 61 });
72 </script> 62 </script>
73 -{% endblock %}  
74 \ No newline at end of file 63 \ No newline at end of file
  64 +{% endblock content %}
courses/templates/topic/index.html
@@ -65,7 +65,7 @@ @@ -65,7 +65,7 @@
65 </div> 65 </div>
66 <div class="panel panel-default"> 66 <div class="panel panel-default">
67 <div class="panel-body"> 67 <div class="panel-body">
68 - {% include "topic/topic_card_student.html" %} 68 + {% include "topic/topic_card.html" %}
69 {% comment %} 69 {% comment %}
70 70
71 71
@@ -116,13 +116,23 @@ @@ -116,13 +116,23 @@
116 </fieldset> 116 </fieldset>
117 </form>--> 117 </form>-->
118 {% endcomment %} 118 {% endcomment %}
119 -  
120 -  
121 -  
122 -  
123 </div> 119 </div>
124 -  
125 -  
126 </div> 120 </div>
127 </div> 121 </div>
  122 + <div class="col-md-6">
  123 + <h3>{% trans 'Students - Specific Exercises' %}</h3>
  124 + <br/>
  125 + </div>
  126 + {# mostra a lista de usuários caso seja um professor ou admin #}
  127 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  128 + {% for user in users %}
  129 + {% include "exercise/card_list_user.html" %}
  130 + {% endfor %}
  131 + {% endif %}
  132 + {# caso seja um estudante, mostra a lista de exercícios proposta a ele #}
  133 + {% if user|has_role:'student'%}
  134 + {% for exercise in exercises %}
  135 + {% include "exercise/card_topic_exercises.html" %}
  136 + {% endfor %}
  137 + {% endif %}
128 {% endblock %} 138 {% endblock %}
courses/templates/topic/replicate.html 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +{% extends 'subject/index.html' %}
  2 +
  3 +{% load static i18n permission_tags widget_tweaks %}
  4 +
  5 +{% block content %}
  6 +
  7 + <div class="panel panel-default">
  8 + <div class="panel-body">
  9 + <form class="form-group " method="post" action="">
  10 + {% csrf_token %}
  11 +
  12 + <div class="form-group {% if topic.name.errors %} has-error{% endif %}">
  13 + <label for="id_name" class="control-label label-static"> {% trans 'Name'%}</label>
  14 + <textarea class="form-control" id="id_name" maxlength="100" rows="1" name="name" placeholder="Name" type="text" required >{{topic.name}}</textarea>
  15 +
  16 + <span class="help-block">{% trans 'Topic name'%}</span>
  17 + </div>
  18 + <div class="form-group {% if topic.description.errors %} has-error{% endif %}">
  19 + <label for="id_description" class="control-label label-static"> {% trans 'Description'%}</label>
  20 + <textarea class="form-control" id="id_description" name="description" placeholder="Description" type="text"> {{topic.description}}</textarea>
  21 +
  22 + <span class="help-block">{% trans 'Topic description'%}</span>
  23 + </div>
  24 +
  25 + <div class="col-lg-offset-4 col-lg-4">
  26 + <button type="submit" class="btn btn-raised btn-primary btn-lg btn-block">{% trans 'Create' %}</button>
  27 +
  28 + </div>
  29 + </form>
  30 + </div>
  31 + </div>
  32 +
  33 + <script type="text/javascript">
  34 + $(document).ready(function() {
  35 + $('#id_description').summernote({height: 300});
  36 + });
  37 + </script>
  38 +{% endblock content %}
courses/templates/topic/replicate_topic.html
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -{% extends 'subject/index.html' %}  
2 -  
3 -{% load static i18n permission_tags widget_tweaks %}  
4 -  
5 -{% block content %}  
6 -  
7 - <div class="panel panel-default">  
8 - <div class="panel-body">  
9 - <form class="form-group " method="post" action="">  
10 - {% csrf_token %}  
11 -  
12 - <div class="form-group {% if topic.name.errors %} has-error{% endif %}">  
13 - <label for="id_name" class="control-label label-static"> {% trans 'Name'%}</label>  
14 - <input class="form-control" id="id_name" maxlength="100" name="name" placeholder="Name" type="text" value={{topic.name}} required />  
15 -  
16 - <span class="help-block">{% trans 'Topic name'%}</span>  
17 - </div>  
18 - <div class="form-group {% if topic.description.errors %} has-error{% endif %}">  
19 - <label for="id_description" class="control-label label-static"> {% trans 'Description'%}</label>  
20 - <textarea class="form-control" id="id_description" name="description" placeholder="Description" type="text"> {{topic.description}}</textarea>  
21 -  
22 - <span class="help-block">{% trans 'Topic description'%}</span>  
23 - </div>  
24 -  
25 - <div class="col-lg-offset-4 col-lg-4">  
26 - <button type="submit" class="btn btn-raised btn-primary btn-lg btn-block">{% trans 'Create' %}</button>  
27 -  
28 - </div>  
29 - </form>  
30 - </div>  
31 - </div>  
32 -  
33 - <script type="text/javascript">  
34 - $(document).ready(function() {  
35 - $('#id_description').summernote({height: 300});  
36 - });  
37 - </script>  
38 -{% endblock content %}  
courses/templates/topic/topic_card.html 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access%}
  2 +
  3 +
  4 +<div class="row">
  5 + <div class="col-xs-6 col-md-6">
  6 + <div class="resource_inline">
  7 + <h4>{% trans "Materials" %}</h4>
  8 + </div>
  9 +
  10 + <ul id="list-materials">
  11 + {% list_topic_file request topic %}
  12 + {% list_topic_link request topic%}
  13 +
  14 + </ul>
  15 + </div>
  16 + <div class="col-xs-6 col-md-6">
  17 + <div class="resource_inline">
  18 + <h4>{% trans "Activities" %}</h4>
  19 + </div>
  20 + <ul>
  21 + <div class="foruns_list">
  22 + {# {% list_topic_exam request topic %} #}
  23 + {% list_topic_poll request topic %}
  24 + {% list_topic_foruns request topic %}
  25 + </div>
  26 + </ul>
  27 + </div>
  28 +</div>
0 \ No newline at end of file 29 \ No newline at end of file
courses/templates/topic/topic_card_student.html
@@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
1 -{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access%}  
2 -  
3 -  
4 -<div class="row">  
5 - <div class="col-xs-6 col-md-6">  
6 - <div class="resource_inline">  
7 - <h4>{% trans "Materials" %}</h4>  
8 - </div>  
9 -  
10 - <ul id="list-materials">  
11 - {% list_topic_file request topic %}  
12 - {% list_topic_link request topic%}  
13 -  
14 - </ul>  
15 - </div>  
16 - <div class="col-xs-4 col-md-4">  
17 - <div class="resource_inline">  
18 - <h4>{% trans "Activities" %}</h4>  
19 - </div>  
20 - <ul>  
21 - <div class="foruns_list">  
22 - {% list_topic_exam request topic %}  
23 - {% list_topic_poll request topic %}  
24 - {% list_topic_foruns request topic %}  
25 - </div>  
26 - </ul>  
27 - </div>  
28 -  
29 -</div>  
courses/urls.py
@@ -6,7 +6,6 @@ urlpatterns = [ @@ -6,7 +6,6 @@ urlpatterns = [
6 url(r'^all-courses/$', views.AllCoursesView.as_view(), name='all_courses'), 6 url(r'^all-courses/$', views.AllCoursesView.as_view(), name='all_courses'),
7 url(r'^create/$', views.CreateCourseView.as_view(), name='create'), 7 url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
8 url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'), 8 url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'),
9 - url(r'^replicate_subject/(?P<slug>[\w_-]+)/$', views.ReplicateSubjectView.as_view(), name='replicate_subject'),  
10 url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'), 9 url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'),
11 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'), 10 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'),
12 url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_course, name='subscribe'), 11 url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_course, name='subscribe'),
@@ -19,10 +18,11 @@ urlpatterns = [ @@ -19,10 +18,11 @@ urlpatterns = [
19 url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), 18 url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'),
20 url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'), 19 url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'),
21 url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'), 20 url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'),
  21 + url(r'^subjects/replicate/(?P<slug>[\w_-]+)/$', views.ReplicateSubjectView.as_view(), name='replicate_subject'),
22 url(r'^subjects/subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_subject, name='subscribe_subject'), 22 url(r'^subjects/subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_subject, name='subscribe_subject'),
23 url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'), 23 url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'),
24 url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.UpdateTopicView.as_view(), name='update_topic'), 24 url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.UpdateTopicView.as_view(), name='update_topic'),
25 - url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.DeleteTopic.as_view(), name='delete_topic'), 25 + url(r'^topics/delete/(?P<slug>[\w_-]+)/$', views.DeleteTopic.as_view(), name='delete_topic'),
26 url(r'^topics/replicate/(?P<slug>[\w_-]+)/$', views.ReplicateTopicView.as_view(), name='replicate_topic'), 26 url(r'^topics/replicate/(?P<slug>[\w_-]+)/$', views.ReplicateTopicView.as_view(), name='replicate_topic'),
27 url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'), 27 url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'),
28 url(r'^subjects/categories$',views.IndexSubjectCategoryView.as_view(), name='subject_category_index'), 28 url(r'^subjects/categories$',views.IndexSubjectCategoryView.as_view(), name='subject_category_index'),
courses/views.py
@@ -56,7 +56,7 @@ def course_category(list_courses): @@ -56,7 +56,7 @@ def course_category(list_courses):
56 if (cat): 56 if (cat):
57 categorys_courses.append(cat) 57 categorys_courses.append(cat)
58 58
59 - return categorys_courses 59 + return sorted(list(categorys_courses),key = lambda x:x.name)
60 60
61 class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): 61 class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
62 62
@@ -93,10 +93,10 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -93,10 +93,10 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
93 list_courses = self.get_queryset().order_by('name') 93 list_courses = self.get_queryset().order_by('name')
94 # categorys_courses = CourseCategory.objects.all() 94 # categorys_courses = CourseCategory.objects.all()
95 elif has_role(self.request.user,'professor'): 95 elif has_role(self.request.user,'professor'):
96 - list_courses = self.get_queryset().filter(professors__in = [self.request.user]) 96 + list_courses = self.get_queryset().filter(professors__in = [self.request.user]).order_by('name')
97 # categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct() 97 # categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct()
98 elif has_role(self.request.user, 'student'): 98 elif has_role(self.request.user, 'student'):
99 - list_courses = self.get_queryset().filter(students__in = [self.request.user]) 99 + list_courses = self.get_queryset().filter(students__in = [self.request.user]).order_by('name')
100 100
101 context['categorys_courses'] = course_category(list_courses) 101 context['categorys_courses'] = course_category(list_courses)
102 return context 102 return context
@@ -136,6 +136,7 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -136,6 +136,7 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView):
136 list_courses = self.get_queryset() 136 list_courses = self.get_queryset()
137 137
138 context['categorys_courses'] = course_category(list_courses) 138 context['categorys_courses'] = course_category(list_courses)
  139 +
139 return context 140 return context
140 141
141 class CreateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView): 142 class CreateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView):
@@ -561,39 +562,6 @@ class SubjectsView(LoginRequiredMixin, LogMixin, generic.ListView): @@ -561,39 +562,6 @@ class SubjectsView(LoginRequiredMixin, LogMixin, generic.ListView):
561 context['files'] = TopicFile.objects.filter(students__name = self.request.user.name) 562 context['files'] = TopicFile.objects.filter(students__name = self.request.user.name)
562 return context 563 return context
563 564
564 -class ReplicateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin,generic.edit.CreateView):  
565 -  
566 - allowed_roles = ['professor', 'system_admin']  
567 - login_url = reverse_lazy("core:home")  
568 - redirect_field_name = 'next'  
569 - template_name = 'subject/replicate.html'  
570 - form_class = SubjectForm  
571 - success_url = reverse_lazy('course:view')  
572 -  
573 - def get_context_data(self, **kwargs):  
574 - context = super(ReplicateSubjectView, self).get_context_data(**kwargs)  
575 - subject = get_object_or_404(Subject, slug=self.kwargs.get('slug'))  
576 -  
577 - if has_role(self.request.user,'system_admin'):  
578 - subjects = Subject.objects.all()  
579 - context['subjects'] = subjects  
580 - elif has_role(self.request.user,'professor'):  
581 - subject = self.request.user.professors_subjects.all()  
582 - categorys_subjects = CategorySubject.objects.all()  
583 -  
584 - context['subject'] = subject  
585 - context['categorys_subjects'] = categorys_subjects  
586 - context['title'] = _("Replicate Subject")  
587 - context['now'] = date.today()  
588 - return context  
589 -  
590 - def form_valid(self, form):  
591 - self.object = form.save()  
592 -  
593 - return super(ReplicateSubjectView, self).form_valid(form)  
594 -  
595 - def get_success_url(self):  
596 - return reverse_lazy('course:view', kwargs={'slug' : self.object.slug})  
597 565
598 class UploadMaterialView(LoginRequiredMixin, generic.edit.CreateView): 566 class UploadMaterialView(LoginRequiredMixin, generic.edit.CreateView):
599 login_url = reverse_lazy("core:home") 567 login_url = reverse_lazy("core:home")
@@ -663,6 +631,11 @@ class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView): @@ -663,6 +631,11 @@ class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView):
663 activitys = Activity.objects.filter(topic__name = topic.name) 631 activitys = Activity.objects.filter(topic__name = topic.name)
664 students_activit = User.objects.filter(activities__in = Activity.objects.all()) 632 students_activit = User.objects.filter(activities__in = Activity.objects.all())
665 materials = Material.objects.filter(topic = topic) 633 materials = Material.objects.filter(topic = topic)
  634 +
  635 + users = User.objects.filter(subject_student__in = Subject.objects.all())
  636 + context['users'] = users
  637 + exercises = Exercise.objects.filter(Q(students=self.request.user)|Q(professors=self.request.user))
  638 + context['exercises'] = exercises
666 639
667 context['topic'] = topic 640 context['topic'] = topic
668 context['subject'] = topic.subject 641 context['subject'] = topic.subject
@@ -1017,13 +990,13 @@ class TopicViewSet(viewsets.ModelViewSet): @@ -1017,13 +990,13 @@ class TopicViewSet(viewsets.ModelViewSet):
1017 class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin,generic.edit.CreateView): 990 class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin,generic.edit.CreateView):
1018 log_component = "course" 991 log_component = "course"
1019 log_resource = "topic" 992 log_resource = "topic"
1020 - log_action = "create" 993 + log_action = "replicate"
1021 log_context = {} 994 log_context = {}
1022 995
1023 allowed_roles = ['professor', 'system_admin'] 996 allowed_roles = ['professor', 'system_admin']
1024 login_url = reverse_lazy("core:home") 997 login_url = reverse_lazy("core:home")
1025 - model = Topic  
1026 - template_name = 'topic/replicate_topic.html' 998 + redirect_field_name = 'next'
  999 + template_name = 'topic/replicate.html'
1027 form_class = TopicForm 1000 form_class = TopicForm
1028 1001
1029 def get_success_url(self): 1002 def get_success_url(self):
@@ -1032,21 +1005,23 @@ class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, Notificati @@ -1032,21 +1005,23 @@ class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, Notificati
1032 def get_context_data(self, **kwargs): 1005 def get_context_data(self, **kwargs):
1033 context = super(ReplicateTopicView, self).get_context_data(**kwargs) 1006 context = super(ReplicateTopicView, self).get_context_data(**kwargs)
1034 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) 1007 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
1035 - subject = topic.subject 1008 + subject = Subject.objects.get(pk = topic.subject_id)
1036 context['course'] = subject.course 1009 context['course'] = subject.course
1037 context['subject'] = subject 1010 context['subject'] = subject
1038 context['subjects'] = subject.course.subjects.all() 1011 context['subjects'] = subject.course.subjects.all()
1039 context['topic'] = topic 1012 context['topic'] = topic
1040 return context 1013 return context
1041 1014
1042 -  
1043 def form_valid(self, form): 1015 def form_valid(self, form):
1044 - self.object.subject = self.object.subject.id 1016 + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  1017 + subject = Subject.objects.get(pk = topic.subject_id)
  1018 +
1045 self.object = form.save(commit = False) 1019 self.object = form.save(commit = False)
  1020 + self.object.topic = topic
  1021 + self.object.subject = subject
1046 self.object.owner = self.request.user 1022 self.object.owner = self.request.user
1047 self.object.save() 1023 self.object.save()
1048 -  
1049 - action = super(ReplicateTopicView, self).createorRetrieveAction("replicate Topic") 1024 + action = super(ReplicateTopicView, self).createorRetrieveAction("create Topic")
1050 super(ReplicateTopicView, self).createNotification("Topic "+ self.object.name + " was created", 1025 super(ReplicateTopicView, self).createNotification("Topic "+ self.object.name + " was created",
1051 resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]), 1026 resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]),
1052 actor=self.request.user, users = self.object.subject.course.students.all() ) 1027 actor=self.request.user, users = self.object.subject.course.students.all() )
@@ -1066,3 +1041,55 @@ class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, Notificati @@ -1066,3 +1041,55 @@ class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, Notificati
1066 super(ReplicateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) 1041 super(ReplicateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
1067 1042
1068 return super(ReplicateTopicView, self).form_valid(form) 1043 return super(ReplicateTopicView, self).form_valid(form)
  1044 +
  1045 +class ReplicateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView):
  1046 + log_component = "course"
  1047 + log_resource = "subject"
  1048 + log_action = "replicate"
  1049 + log_context = {}
  1050 +
  1051 + allowed_roles = ['professor', 'system_admin']
  1052 + login_url = reverse_lazy("core:home")
  1053 + redirect_field_name = 'next'
  1054 + template_name = 'subject/replicate.html'
  1055 + form_class = SubjectForm
  1056 +
  1057 + def get_success_url(self):
  1058 + return reverse_lazy('course:view_subject', kwargs={'slug' : self.object.slug})
  1059 +
  1060 + def get_context_data(self, **kwargs):
  1061 + context = super(ReplicateSubjectView, self).get_context_data(**kwargs)
  1062 + subject = get_object_or_404(Subject, slug = self.kwargs.get('slug'))
  1063 + course = Course.objects.get(pk=subject.course_id)
  1064 + context['course'] = course
  1065 + context['subjects'] = course.subjects.filter(Q(visible=True) | Q(professors__in=[self.request.user]))
  1066 + context['subject'] = subject
  1067 + if (has_role(self.request.user,'system_admin')):
  1068 + context['subjects'] = course.subjects.all()
  1069 + return context
  1070 +
  1071 + def form_valid(self, form):
  1072 + subject = get_object_or_404(Subject, slug = self.kwargs.get('slug'))
  1073 + course = Course.objects.get(pk=subject.course_id)
  1074 +
  1075 + self.object = form.save(commit = False)
  1076 + self.object.course = course
  1077 + self.object.save()
  1078 + self.object.professors.add(self.request.user)
  1079 + if self.object.visible:
  1080 + super(ReplicateSubjectView, self).createNotification( " created subject " + self.object.name, resource_name=self.object.name,
  1081 + resource_slug = self.object.slug, actor=self.request.user, users= self.object.course.students.all(),
  1082 + resource_link = reverse('course:view_subject', args=[self.object.slug]))
  1083 +
  1084 + self.log_context['subject_id'] = self.object.id
  1085 + self.log_context['subject_name'] = self.object.name
  1086 + self.log_context['subject_slug'] = self.object.slug
  1087 + self.log_context['course_id'] = course.id
  1088 + self.log_context['course_name'] = course.name
  1089 + self.log_context['course_slug'] = course.slug
  1090 + self.log_context['course_category_id'] = course.category.id
  1091 + self.log_context['course_category_name'] = course.category.name
  1092 +
  1093 + super(ReplicateSubjectView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  1094 +
  1095 + return super(ReplicateSubjectView, self).form_valid(form)
exam/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.db import migrations, models 5 from django.db import migrations, models
@@ -24,8 +24,8 @@ class Migration(migrations.Migration): @@ -24,8 +24,8 @@ class Migration(migrations.Migration):
24 ], 24 ],
25 options={ 25 options={
26 'verbose_name_plural': 'Answers', 26 'verbose_name_plural': 'Answers',
27 - 'ordering': ('order',),  
28 'verbose_name': 'Answer', 27 'verbose_name': 'Answer',
  28 + 'ordering': ('order',),
29 }, 29 },
30 ), 30 ),
31 migrations.CreateModel( 31 migrations.CreateModel(
exam/migrations/0002_auto_20161116_1057.py
@@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 13:57  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.conf import settings  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - ('exam', '0001_initial'),  
16 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
17 - ]  
18 -  
19 - operations = [  
20 - migrations.AddField(  
21 - model_name='answersstudent',  
22 - name='student',  
23 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student', to=settings.AUTH_USER_MODEL, verbose_name='Student'),  
24 - ),  
25 - migrations.AddField(  
26 - model_name='answer',  
27 - name='exam',  
28 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='exam.Exam', verbose_name='Answers'),  
29 - ),  
30 - ]  
exam/migrations/0002_auto_20161117_0217.py 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-17 05:17
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + initial = True
  13 +
  14 + dependencies = [
  15 + ('exam', '0001_initial'),
  16 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  17 + ]
  18 +
  19 + operations = [
  20 + migrations.AddField(
  21 + model_name='answersstudent',
  22 + name='student',
  23 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student', to=settings.AUTH_USER_MODEL, verbose_name='Student'),
  24 + ),
  25 + migrations.AddField(
  26 + model_name='answer',
  27 + name='exam',
  28 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='exam.Exam', verbose_name='Answers'),
  29 + ),
  30 + ]
exercise/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin @@ -2,7 +2,7 @@ from django.contrib import admin
2 from .models import Exercise 2 from .models import Exercise
3 3
4 class ExerciseAdmin(admin.ModelAdmin): 4 class ExerciseAdmin(admin.ModelAdmin):
5 - list_display = ['name']  
6 - search_fields = ['name'] 5 + list_display = ['name_exercise']
  6 + search_fields = ['name_exercise']
7 7
8 admin.site.register(Exercise, ExerciseAdmin) 8 admin.site.register(Exercise, ExerciseAdmin)
exercise/forms.py
@@ -9,11 +9,13 @@ class ExerciseForm(forms.ModelForm): @@ -9,11 +9,13 @@ class ExerciseForm(forms.ModelForm):
9 9
10 class Meta: 10 class Meta:
11 model = Exercise 11 model = Exercise
12 - fields = ['name', 'file'] 12 + fields = ['name_exercise', 'description', 'init_date',
  13 + 'end_date', 'file']
13 14
14 15
15 class UpdateExerciseForm(forms.ModelForm): 16 class UpdateExerciseForm(forms.ModelForm):
16 17
17 class Meta: 18 class Meta:
18 model = Exercise 19 model = Exercise
19 - fields = ['name', 'file'] 20 + fields = ['name_exercise', 'description', 'init_date',
  21 + 'end_date', 'grade', 'file']
exercise/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 08:09
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
  5 +from decimal import Decimal
  6 +from django.conf import settings
5 from django.db import migrations, models 7 from django.db import migrations, models
6 import django.db.models.deletion 8 import django.db.models.deletion
  9 +import exercise.models
7 10
8 11
9 class Migration(migrations.Migration): 12 class Migration(migrations.Migration):
@@ -11,7 +14,9 @@ class Migration(migrations.Migration): @@ -11,7 +14,9 @@ class Migration(migrations.Migration):
11 initial = True 14 initial = True
12 15
13 dependencies = [ 16 dependencies = [
14 - ('courses', '0001_initial'), 17 + ('courses', '0002_auto_20161117_0217'),
  18 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  19 + ('core', '0002_auto_20161117_0217'),
15 ] 20 ]
16 21
17 operations = [ 22 operations = [
@@ -19,8 +24,15 @@ class Migration(migrations.Migration): @@ -19,8 +24,15 @@ class Migration(migrations.Migration):
19 name='Exercise', 24 name='Exercise',
20 fields=[ 25 fields=[
21 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 26 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 - ('file', models.FileField(upload_to='uploads/%Y/%m/%d')),  
23 - ('name', models.CharField(max_length=100)), 27 + ('name_exercise', models.CharField(max_length=100, verbose_name='Exercise Name')),
  28 + ('description', models.TextField(blank=True, verbose_name='Description')),
  29 + ('init_date', models.DateField(verbose_name='Begin of Subject Date')),
  30 + ('end_date', models.DateField(verbose_name='End of Subject Date')),
  31 + ('grade', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=20, null=True)),
  32 + ('file', models.FileField(upload_to=exercise.models.file_path)),
  33 + ('file_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercise_type', to='core.MimeType', verbose_name='Type file')),
  34 + ('professors', models.ManyToManyField(blank=True, related_name='professors_exercise', to=settings.AUTH_USER_MODEL, verbose_name='Professors')),
  35 + ('students', models.ManyToManyField(blank=True, related_name='subject_exercise', to=settings.AUTH_USER_MODEL, verbose_name='Students')),
24 ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='courses.Topic', verbose_name='Topic')), 36 ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='courses.Topic', verbose_name='Topic')),
25 ], 37 ],
26 ), 38 ),
exercise/migrations/0002_auto_20161117_0555.py 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-17 08:55
  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 + dependencies = [
  12 + ('exercise', '0001_initial'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AlterField(
  17 + model_name='exercise',
  18 + name='file',
  19 + field=models.FileField(upload_to='uploads/%Y/%m/%d'),
  20 + ),
  21 + migrations.AlterField(
  22 + model_name='exercise',
  23 + name='name_exercise',
  24 + field=models.CharField(max_length=100, verbose_name='Name'),
  25 + ),
  26 + migrations.AlterField(
  27 + model_name='exercise',
  28 + name='topic',
  29 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercise_topic', to='courses.Topic', verbose_name='Topic'),
  30 + ),
  31 + ]
exercise/migrations/0003_auto_20161118_2242.py 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-19 01:42
  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 + dependencies = [
  12 + ('exercise', '0002_auto_20161117_0555'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AlterField(
  17 + model_name='exercise',
  18 + name='file_type',
  19 + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='exercise_type', to='core.MimeType', verbose_name='Type file'),
  20 + ),
  21 + ]
exercise/models.py
1 -from django.db import models  
2 from courses.models import Topic 1 from courses.models import Topic
  2 +from decimal import Decimal
  3 +from django.db import models
3 from django.utils.translation import ugettext_lazy as _ 4 from django.utils.translation import ugettext_lazy as _
  5 +from users.models import User
  6 +from core.models import MimeType
4 7
5 """ 8 """
6 Function to return the path where the file should be saved 9 Function to return the path where the file should be saved
@@ -17,6 +20,17 @@ It represents the Exercises inside topic. @@ -17,6 +20,17 @@ It represents the Exercises inside topic.
17 20
18 21
19 class Exercise(models.Model): 22 class Exercise(models.Model):
20 - topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='exercises') 23 +
  24 + name_exercise = models.CharField(_('Name'), max_length=100)
  25 + description = models.TextField(_('Description'), blank=True)
  26 + init_date = models.DateField(_('Begin of Subject Date'))
  27 + end_date = models.DateField(_('End of Subject Date'))
  28 + grade = models.DecimalField(max_digits=20, decimal_places=2, default=Decimal('0.00'), null=True)
  29 + topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='exercise_topic')
  30 + professors = models.ManyToManyField(User, verbose_name=_('Professors'), related_name='professors_exercise', blank=True)
  31 + students = models.ManyToManyField(User, verbose_name=_('Students'), related_name='subject_exercise', blank = True)
21 file = models.FileField(upload_to='uploads/%Y/%m/%d') 32 file = models.FileField(upload_to='uploads/%Y/%m/%d')
22 - name = models.CharField(max_length=100) 33 + file_type = models.ForeignKey(MimeType, verbose_name=_('Type file'), related_name='exercise_type',null=True)
  34 +
  35 + def __str__(self):
  36 + return self.name_exercise
23 \ No newline at end of file 37 \ No newline at end of file
exercise/static/js/exercise.js
1 -function get_modal_link(url, id,div_content){ 1 +function get_modal_exercise(url, id,div_content){
2 $.get(url, function (data) { 2 $.get(url, function (data) {
3 $(div_content).detach(); 3 $(div_content).detach();
4 $(div_content).append(data); 4 $(div_content).append(data);
exercise/templates/exercise/card_list_user.html 0 → 100644
@@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
  1 +{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access list_topic_exercises %}
  2 +
  3 +<div class="col-md-12 col-sm-12 col-lg-12">
  4 + <div class="panel-group accordion ui-accordion ui-widget ui-helper-reset ui-sortable" role="tablist" aria-multiselectable="false">
  5 + <div class="group"><div class="panel panel-default">
  6 + <div class="panel-heading topic ui-sortable-handle" role="tab">
  7 + <div class="row">
  8 + <div class="col-md-1 moreAccordion" data-toggle="collapse" data-parent="#accordion-{{user.id}}" href=".collapseTopic-{{user.id}}" aria-expanded="false" aria-controls="collapseTopic-{{user.id}}">
  9 + <button class="btn btn-default btn-sm caret-square"><i class="fa fa-caret-square-o-down fa-2x" aria-hidden="true"></i></button>
  10 + </div>
  11 + <div class="col-xs-9 col-md-9 titleTopic">
  12 + <a href="" role="button">
  13 + <h4>{{user|capfirst}}</h4>
  14 + </a>
  15 + </div>
  16 + </div>
  17 + </div>
  18 + <div class="panel-collapse collapseTopic-{{user.id}} collapse in" role="tabpanel" aria-labelledby="heading_{{user.id}}" aria-expanded="true" aria-hidden="false">
  19 + <div class="panel-body">
  20 + <div class="row">
  21 + <div class="col-md-4">
  22 + <div class="resource_inline">
  23 + <h4>{% trans 'Grade' %}</h4>
  24 + </div>
  25 + <div class="resource_inline">
  26 + {# dropdown de create exercício #}
  27 + <div class="dropdown">
  28 + <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a>
  29 + <ul class="dropdown-menu" aria-labelledby="dLabel">
  30 + <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Give a grade' %}</a></li>
  31 + </ul>
  32 + </div>
  33 + </div>
  34 + </div>
  35 + <div class="col-md-4">
  36 + <div class="resource_inline">
  37 + <h4>{% trans 'Delivery' %}</h4>
  38 + </div>
  39 + {% for exercise in exercises %}
  40 + <li><a href="{{exercise.file.url}}" target="_blank">{{exercise.name_exercise}}</a></li>
  41 + {% endfor %}
  42 + </div>
  43 + <div class="col-md-4">
  44 + <div class="resource_inline">
  45 + <h4>{% trans 'Create' %}</h4>
  46 + </div>
  47 + <div class="resource_inline">
  48 + {# dropdown de create exercício #}
  49 + <div class="dropdown">
  50 + <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a>
  51 + <ul class="dropdown-menu" aria-labelledby="dLabel">
  52 + <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Create a specific exercise' %}</a></li>
  53 + </ul>
  54 + </div>
  55 + </div>
  56 + {% include "exercise/create_exercise.html" %}
  57 + </div>
  58 + </div>
  59 + </div>
  60 + </div>
  61 + </div>
  62 + </div>
  63 +</div>
  64 +</div>
0 \ No newline at end of file 65 \ No newline at end of file
exercise/templates/exercise/card_topic_exercises.html 0 → 100644
@@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
  1 +{% load static widget_tweaks i18n %}
  2 +
  3 +<div class="col-lg-4 col-xs-4 col-sm-4">
  4 + <div class="panel panel-default">
  5 + <div class="panel-body">
  6 + <form class="form-horizontal">
  7 + <fieldset>
  8 + <center><legend>{{exercise.name_exercise}}</legend></center>
  9 + <div class="container-fluid">
  10 + <div class="form-group">
  11 + <label class="col-md-2 col-xs-2 col-sm-2 control-label">Describe: </label><br>
  12 + {% if exercise.description%}
  13 + {{exercise.description}}
  14 + {% else %}
  15 + {% trans "Don't have description" %}
  16 + {% endif %}
  17 + </div>
  18 + <div class="form-group">
  19 + <label class="col-md-2 col-xs-2 col-sm-2 control-label">Opening: </label><br>{{exercise.init_date}}
  20 +
  21 + </div>
  22 + <div class="form-group">
  23 + <label class="col-md-2 col-xs-2 col-sm-2 control-label">Ending: </label><br>{{exercise.end_date}}
  24 +
  25 + </div>
  26 + <div class="form-group">
  27 + <label for="nota" class="col-md-2 control-label">NOTA:
  28 + {% if exercise.grade %}
  29 + <div class="col-md-4">
  30 + <p id="nota" class="form-control">
  31 + {{exercise.grade}}
  32 + </p>
  33 + </div>
  34 + {% else %}
  35 + {% trans 'Not yet' %}
  36 + {% endif %}
  37 + </label>
  38 + </div>
  39 + {% if exercise.file %}
  40 + <div class="form-group">
  41 + <label for="DelExc" class="col-md-4 control-label"> <i class="fa fa-file-archive-o fa-3x" aria-hidden="true">
  42 + <a href="{{exercise.file.url}}" target="_blank">{% trans 'File' %}</a>
  43 + </i>
  44 + </div>
  45 + {% else %}
  46 + <p>{% trans 'Exercise not yet' %}</p>
  47 + {% endif %}
  48 + {% if not exercise.grade %}
  49 + <div class="form-group">
  50 + <label class="col-md-6 control-label"><i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>{% trans 'Teacher waiting corretion' %}
  51 + </div>
  52 + {% endif %}
  53 + </div>
  54 +
  55 + </fieldset>
  56 + </form>
  57 +
  58 + </div>
  59 + </div>
  60 +</div>
0 \ No newline at end of file 61 \ No newline at end of file
exercise/templates/exercise/create_exercise.html
@@ -9,75 +9,104 @@ @@ -9,75 +9,104 @@
9 </div> 9 </div>
10 <div class="modal-body"> 10 <div class="modal-body">
11 <!-- Card --> 11 <!-- Card -->
12 - <form method="post" action="" id="form-exercise" enctype="multipart/form-data"> 12 + <form class="form-horizontal" method="post" id="form-exercise" enctype="multipart/form-data">
13 {% csrf_token %} 13 {% csrf_token %}
14 {% if messages %} 14 {% if messages %}
15 - {% for message in messages %}  
16 - <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">  
17 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
18 - <span aria-hidden="true">&times;</span> 15 + {% for message in messages %}
  16 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  17 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  18 + <span aria-hidden="true">&times;</span>
  19 + </button>
  20 + <p>{{ message }}</p>
  21 + </div>
  22 + {% endfor %}
  23 + {% endif %}
  24 + <fieldset>
  25 + {% for field in form %}
  26 + <div class="form-group is-empy{% if form.has_error %} has-error {% endif %} is-fileinput">
  27 + <div class="col-md-12">
  28 + {% if field.field.required %}
  29 + <label for="{{ field.auto_id }}" class="control-label">{{ field.label }}<span>*</span></label>
  30 + {% else %}
  31 + <label for="{{ field.auto_id }}" class=" control-label">{{ field.label }}</label>
  32 + {% endif %}
  33 + {% if field.auto_id == 'id_file' %}
  34 + {% render_field field class='form-control input-sm' %}
  35 + <div class="input-group">
  36 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">
  37 + <span class="input-group-btn input-group-sm">
  38 + <button type="button" class="btn btn-fab btn-fab-mini">
  39 + <i class="material-icons">attach_file</i>
19 </button> 40 </button>
20 - <p>{{ message }}</p> 41 + </span>
21 </div> 42 </div>
22 - {% endfor %}  
23 - {% endif %}  
24 - {% for field in form %}  
25 - <div class ="form-group">  
26 - {% if field.field.required %}  
27 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
28 - {% endif %}  
29 - {% render_field field class='form-control input-sm' %} 43 + {% else %}
  44 + {% render_field field class='form-control input-sm' %}
  45 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  46 + {% endif %}
  47 + </div>
  48 +
30 {% if field.errors %} 49 {% if field.errors %}
31 - <div class="alert alert-danger alert-dismissible clearfix" role="alert">  
32 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
33 - <span aria-hidden="true">&times;</span>  
34 - </button>  
35 - <ul>  
36 - {% for error in field.errors %}  
37 - <li>{{ error }}</li>  
38 - {% endfor %}  
39 - </ul>  
40 - </div> 50 + <div class="alert alert-danger alert-dismissible clearfix" role="alert">
  51 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  52 + <span aria-hidden="true">&times;</span>
  53 + </button>
  54 + <ul>
  55 + {% for error in field.errors %}
  56 + <li>{{ error }}</li>
  57 + {% endfor %}
  58 + </ul>
  59 + </div>
41 {% endif %} 60 {% endif %}
42 </div> 61 </div>
43 - {% endfor %}  
44 - <div class="form-group">  
45 - <button type="button" class="btn btn-raised btn-default " data-dismiss="modal">{% trans "Cancel" %}</button>  
46 - <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>  
47 - </div>  
48 - <!-- .end Card -->  
49 - </div>  
50 - </div>  
51 - </div> 62 + {% endfor %}
  63 +
  64 + <div class="form-group">
  65 + <div class="col-md-12 text-center">
  66 + <p><b>{% trans 'The file size shouldnt exceed 10MB' %}</b></p>
  67 + </div>
  68 + </div>
  69 +
  70 + <div class="form-group">
  71 + <div class="col-md-12">
  72 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  73 + <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
  74 + </div>
  75 + </div>
  76 + </fieldset>
  77 + </form>
  78 + <!-- .end Card -->
  79 + </div>
  80 + </div>
  81 + </div>
52 </div> 82 </div>
53 <!-- EndModal --> 83 <!-- EndModal -->
54 -<script src="{% static 'js/exercises.js' %}"></script>  
55 <script type="text/javascript"> 84 <script type="text/javascript">
56 $("#form-exercise").submit(function(event) { 85 $("#form-exercise").submit(function(event) {
57 - $("#createExercisesModal").modal("hide");  
58 - var data = new FormData($('#form-exercise').get(0));  
59 - $.ajax({  
60 - url: "{% url 'course:exercise:create_exercise' topic.slug %}",  
61 - type: $("#form-exercise").attr('method'),  
62 - data: data,  
63 - cache: false,  
64 - processData: false,  
65 - contentType: false,  
66 - success: function(data) {  
67 - $('#requisicoes_ajax').empty();  
68 - $('#list-topic{{ topic.id }}-exercises').append(data);  
69 - $('#list-topic{{ topic.id }}-exercises-edit').append(data);  
70 - alertify.success('Exercise successfully created!')  
71 - },  
72 - error: function(data){  
73 - $('#requisicoes_ajax').empty();  
74 - $('#requisicoes_ajax').append(data.responseText);  
75 - $('#createExercisesModal').modal('show');  
76 - alertify.alert('Invalid exercise, insert a valid one!');  
77 - $('div.modal-backdrop.fade.in').remove();  
78 - setTimeout(function () { location.reload(1); }, 1000);  
79 - }  
80 - });  
81 - event.preventDefault();  
82 - }); 86 + $("#createExercisesModal").modal("hide");
  87 + var data = new FormData($('#form-exercise').get(0));
  88 + $.ajax({
  89 + url: "{% url 'course:exercise:create_exercise' topic.slug %}",
  90 + type: $("#form-exercise").attr('method'),
  91 + data: data,
  92 + cache: false,
  93 + processData: false,
  94 + contentType: false,
  95 + success: function(data) {
  96 + $('#createExercisesModal').modal('hide');
  97 + $('#list-topic{{ topic.id }}-exercises').append(data);
  98 + $('#list-topic{{ topic.id }}-exercises-edit').append(data);
  99 + alertify.success('Exercise successfully created!')
  100 + },
  101 + error: function(data){
  102 + $('#requisicoes_ajax').empty();
  103 + $('#requisicoes_ajax').append(data.responseText);
  104 + $('#createExercisesModal').modal('show');
  105 + alertify.alert('Invalid exercise, insert a valid one!');
  106 + $('div.modal-backdrop.fade.in').remove();
  107 +
  108 + }
  109 + });
  110 + event.preventDefault();
  111 + });
83 </script> 112 </script>
exercise/templates/exercise/exercise_edit.html
1 {% load static i18n list_topic_foruns permission_tags %} 1 {% load static i18n list_topic_foruns permission_tags %}
2 -<div id="exercise-topic{{ exercise.id }}-exercises-edit"> 2 +<div id="exercise-topic{{ topic.id }}-exercises-edit">
3 {% for exercise in exercises %} 3 {% for exercise in exercises %}
4 <li class="icon_edit_remove" id = "exercise_edit_icon_{{ exercise.slug }}"> <a href="javascript:modal.get('', '#exercisesModalEdit', '#requisicoes_ajax')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('', '#exerciseDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> 4 <li class="icon_edit_remove" id = "exercise_edit_icon_{{ exercise.slug }}"> <a href="javascript:modal.get('', '#exercisesModalEdit', '#requisicoes_ajax')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('', '#exerciseDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li>
5 <li id = "exercise_edit_{{ exercise.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('', '#viewExerciseModal','#requisicoes_ajax')">{{exercise.name}}</a></li> 5 <li id = "exercise_edit_{{ exercise.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('', '#viewExerciseModal','#requisicoes_ajax')">{{exercise.name}}</a></li>
exercise/templates/exercise/render_exercise.html 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<li id="exercise_{{ exercise.slug }}"><i class="material-icons">{{ exercise.file_type.icon }}</i> <a href="{{ exercise.file_url.url }}" target="_blank">{{ exercise.name }}</a></li>
0 \ No newline at end of file 2 \ No newline at end of file
exercise/templatetags/list_topic_exercises.py
@@ -5,21 +5,21 @@ register = template.Library() @@ -5,21 +5,21 @@ register = template.Library()
5 5
6 6
7 @register.inclusion_tag('exercise/exercise_list.html') 7 @register.inclusion_tag('exercise/exercise_list.html')
8 -def list_topic_exercise(request): 8 +def list_topic_exercise(request, topic):
9 context = { 9 context = {
10 'request': request, 10 'request': request,
11 } 11 }
12 - context['exercises'] = Exercise.objects.all() 12 + context['exercises'] = Exercise.objects.filter(topic=topic)
13 13
14 return context 14 return context
15 15
16 16
17 @register.inclusion_tag('exercise/exercise_edit.html') 17 @register.inclusion_tag('exercise/exercise_edit.html')
18 -def list_topic_exercise_edit(request, exercise): 18 +def list_topic_exercise_edit(request, topic):
19 context = { 19 context = {
20 'request': request, 20 'request': request,
21 } 21 }
22 - context['exercises'] = Exercise.objects.all()  
23 - context['exercise'] = exercise 22 + context['exercises'] = Exercise.objects.filter(topic = topic)
  23 + context['topic'] = topic
24 24
25 return context 25 return context
exercise/views.py
1 from .forms import ExerciseForm, UpdateExerciseForm 1 from .forms import ExerciseForm, UpdateExerciseForm
2 from .models import Exercise 2 from .models import Exercise
3 -from files.utils import mime_type_to_material_icons  
4 from core.decorators import log_decorator 3 from core.decorators import log_decorator
5 from core.mixins import LogMixin, NotificationMixin 4 from core.mixins import LogMixin, NotificationMixin
6 from core.models import Log, MimeType 5 from core.models import Log, MimeType
@@ -13,8 +12,10 @@ from django.core.urlresolvers import reverse_lazy @@ -13,8 +12,10 @@ from django.core.urlresolvers import reverse_lazy
13 from django.shortcuts import render, get_object_or_404, redirect 12 from django.shortcuts import render, get_object_or_404, redirect
14 from django.urls import reverse 13 from django.urls import reverse
15 from django.views import generic 14 from django.views import generic
  15 +from files.utils import mime_type_to_material_icons
16 from rolepermissions.mixins import HasRoleMixin 16 from rolepermissions.mixins import HasRoleMixin
17 from rolepermissions.verifications import has_role 17 from rolepermissions.verifications import has_role
  18 +from users.models import User
18 19
19 20
20 class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView): 21 class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView):
@@ -23,7 +24,7 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -23,7 +24,7 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
23 log_action = 'create' 24 log_action = 'create'
24 log_component = {} 25 log_component = {}
25 26
26 - allowed_roles = ['student'] 27 + allowed_roles = ['professor', 'student']
27 login_url = reverse_lazy("core:home") 28 login_url = reverse_lazy("core:home")
28 redirect_field_name = 'next' 29 redirect_field_name = 'next'
29 model = Exercise 30 model = Exercise
@@ -35,7 +36,6 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -35,7 +36,6 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
35 log_resource = "exercise" 36 log_resource = "exercise"
36 log_action = "create" 37 log_action = "create"
37 log_context = {} 38 log_context = {}
38 - context_object_name = 'form'  
39 39
40 def form_invalid(self, form, **kwargs): 40 def form_invalid(self, form, **kwargs):
41 context = super(CreateExercise, self).form_invalid(form) 41 context = super(CreateExercise, self).form_invalid(form)
@@ -47,19 +47,16 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -47,19 +47,16 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
47 self.object = form.save(commit = False) 47 self.object = form.save(commit = False)
48 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) 48 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
49 self.object.topic = topic 49 self.object.topic = topic
50 -  
51 - self.object.name = str(self.object)  
52 -  
53 50
54 # Set MimeType 51 # Set MimeType
55 - exercise = self.request.FILES['exercise_url'] 52 + exercise = self.request.FILES['file']
56 try: 53 try:
57 if exercise: 54 if exercise:
58 exercise_type = exercise.content_type 55 exercise_type = exercise.content_type
59 56
60 # Check if exist a mimetype in database 57 # Check if exist a mimetype in database
61 try: 58 try:
62 - self.object.exercise_type = MimeType.objects.get(typ = exercise_type) 59 + self.object.file_type = MimeType.objects.get(typ = exercise_type)
63 # Create if not 60 # Create if not
64 except: 61 except:
65 mtype = MimeType.objects.create( 62 mtype = MimeType.objects.create(
@@ -67,11 +64,14 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -67,11 +64,14 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
67 icon = mime_type_to_material_icons[exercise_type] 64 icon = mime_type_to_material_icons[exercise_type]
68 ) 65 )
69 mtype.save() 66 mtype.save()
70 - self.object.exercise_type = mtype 67 + self.object.file_type = mtype
71 except: 68 except:
72 print('Exercise not uploaded') 69 print('Exercise not uploaded')
73 70
74 self.object.save() 71 self.object.save()
  72 + self.object.professors = topic.subject.professors.all()
  73 + self.object.students = topic.subject.students.all()
  74 + self.object.save()
75 #CREATE LOG 75 #CREATE LOG
76 self.log_context['topic_id'] = topic.id 76 self.log_context['topic_id'] = topic.id
77 self.log_context['topic_name'] = topic.name 77 self.log_context['topic_name'] = topic.name
@@ -85,12 +85,12 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -85,12 +85,12 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
85 85
86 86
87 #CREATE NOTIFICATION 87 #CREATE NOTIFICATION
88 - super(CreateExercise, self).createNotification(message="uploaded a Exercise "+ self.object.name, actor=self.request.user,  
89 - resource_name=self.object.name, resource_link= reverse('course:view_topic', args=[self.object.topic.slug]), 88 + super(CreateExercise, self).createNotification(message="uploaded a Exercise "+ self.object.name_exercise, actor=self.request.user,
  89 + resource_name=self.object.name_exercise, resource_link= reverse('course:view_topic', args=[self.object.topic.slug]),
90 users=self.object.topic.subject.students.all()) 90 users=self.object.topic.subject.students.all())
91 91
92 self.log_context['exercise_id'] = self.object.id 92 self.log_context['exercise_id'] = self.object.id
93 - self.log_context['exercise_name'] = self.object.name 93 + self.log_context['exercise_name'] = self.object.name_exercise
94 self.log_context['topic_id'] = self.object.topic.id 94 self.log_context['topic_id'] = self.object.topic.id
95 self.log_context['topic_name'] = self.object.topic.name 95 self.log_context['topic_name'] = self.object.topic.name
96 self.log_context['topic_slug'] = self.object.topic.slug 96 self.log_context['topic_slug'] = self.object.topic.slug
@@ -137,7 +137,7 @@ def render_exercise(request, id): @@ -137,7 +137,7 @@ def render_exercise(request, id):
137 137
138 log_context = {} 138 log_context = {}
139 log_context['exercise_id'] = exercise.id 139 log_context['exercise_id'] = exercise.id
140 - log_context['exercise_name'] = exercise.name 140 + log_context['exercise_name'] = exercise.name_exercise
141 log_context['topic_id'] = exercise.topic.id 141 log_context['topic_id'] = exercise.topic.id
142 log_context['topic_name'] = exercise.topic.name 142 log_context['topic_name'] = exercise.topic.name
143 log_context['topic_slug'] = exercise.topic.slug 143 log_context['topic_slug'] = exercise.topic.slug
files/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.db import migrations, models 5 from django.db import migrations, models
@@ -12,8 +12,8 @@ class Migration(migrations.Migration): @@ -12,8 +12,8 @@ class Migration(migrations.Migration):
12 initial = True 12 initial = True
13 13
14 dependencies = [ 14 dependencies = [
15 - ('core', '0001_initial'),  
16 ('courses', '0001_initial'), 15 ('courses', '0001_initial'),
  16 + ('core', '0001_initial'),
17 ] 17 ]
18 18
19 operations = [ 19 operations = [
@@ -27,8 +27,8 @@ class Migration(migrations.Migration): @@ -27,8 +27,8 @@ class Migration(migrations.Migration):
27 ], 27 ],
28 options={ 28 options={
29 'verbose_name_plural': 'Files', 29 'verbose_name_plural': 'Files',
30 - 'ordering': ('-id',),  
31 'verbose_name': 'File', 30 'verbose_name': 'File',
  31 + 'ordering': ('-id',),
32 }, 32 },
33 bases=('courses.material',), 33 bases=('courses.material',),
34 ), 34 ),
files/migrations/0002_topicfile_professor.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.conf import settings 5 from django.conf import settings
forum/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.db import migrations, models 5 from django.db import migrations, models
forum/migrations/0002_auto_20161116_1057.py
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 13:57  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.conf import settings  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - ('forum', '0001_initial'),  
16 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
17 - ]  
18 -  
19 - operations = [  
20 - migrations.AddField(  
21 - model_name='postanswer',  
22 - name='user',  
23 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor'),  
24 - ),  
25 - migrations.AddField(  
26 - model_name='post',  
27 - name='forum',  
28 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Forum', verbose_name='Forum'),  
29 - ),  
30 - migrations.AddField(  
31 - model_name='post',  
32 - name='user',  
33 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor'),  
34 - ),  
35 - ]  
forum/migrations/0002_auto_20161117_0217.py 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-17 05:17
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + initial = True
  13 +
  14 + dependencies = [
  15 + ('forum', '0001_initial'),
  16 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  17 + ]
  18 +
  19 + operations = [
  20 + migrations.AddField(
  21 + model_name='postanswer',
  22 + name='user',
  23 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor'),
  24 + ),
  25 + migrations.AddField(
  26 + model_name='post',
  27 + name='forum',
  28 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Forum', verbose_name='Forum'),
  29 + ),
  30 + migrations.AddField(
  31 + model_name='post',
  32 + name='user',
  33 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor'),
  34 + ),
  35 + ]
links/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.db import migrations, models 5 from django.db import migrations, models
@@ -19,8 +19,8 @@ class Migration(migrations.Migration): @@ -19,8 +19,8 @@ class Migration(migrations.Migration):
19 name='Link', 19 name='Link',
20 fields=[ 20 fields=[
21 ('material_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='courses.Material')), 21 ('material_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='courses.Material')),
22 - ('link_url', models.URLField()),  
23 - ('link_description', models.CharField(max_length=200)), 22 + ('link_url', models.URLField(verbose_name='Link_URL')),
  23 + ('link_description', models.CharField(max_length=200, verbose_name='Description')),
24 ('image', models.ImageField(blank=True, upload_to='links/')), 24 ('image', models.ImageField(blank=True, upload_to='links/')),
25 ], 25 ],
26 options={ 26 options={
links/migrations/0002_auto_20161116_1338.py
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 16:38  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.db import migrations, models  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - ('links', '0001_initial'),  
12 - ]  
13 -  
14 - operations = [  
15 - migrations.AlterField(  
16 - model_name='link',  
17 - name='link_description',  
18 - field=models.TextField(verbose_name='Description'),  
19 - ),  
20 - migrations.AlterField(  
21 - model_name='link',  
22 - name='link_url',  
23 - field=models.URLField(verbose_name='Link_URL'),  
24 - ),  
25 - ]  
links/migrations/0003_auto_20161116_1340.py
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 16:40  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.db import migrations, models  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - ('links', '0002_auto_20161116_1338'),  
12 - ]  
13 -  
14 - operations = [  
15 - migrations.AlterField(  
16 - model_name='link',  
17 - name='link_description',  
18 - field=models.TextField(max_length=200, verbose_name='Description'),  
19 - ),  
20 - ]  
links/migrations/0004_auto_20161116_1341.py
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 16:41  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.db import migrations, models  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - ('links', '0003_auto_20161116_1340'),  
12 - ]  
13 -  
14 - operations = [  
15 - migrations.AlterField(  
16 - model_name='link',  
17 - name='link_description',  
18 - field=models.CharField(max_length=200, verbose_name='Description'),  
19 - ),  
20 - ]  
poll/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from django.db import migrations, models 5 from django.db import migrations, models
@@ -24,8 +24,8 @@ class Migration(migrations.Migration): @@ -24,8 +24,8 @@ class Migration(migrations.Migration):
24 ], 24 ],
25 options={ 25 options={
26 'verbose_name_plural': 'Answers', 26 'verbose_name_plural': 'Answers',
27 - 'ordering': ('order',),  
28 'verbose_name': 'Answer', 27 'verbose_name': 'Answer',
  28 + 'ordering': ('order',),
29 }, 29 },
30 ), 30 ),
31 migrations.CreateModel( 31 migrations.CreateModel(
poll/migrations/0002_auto_20161116_1057.py
@@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-16 13:57  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.conf import settings  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - ('poll', '0001_initial'),  
16 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
17 - ]  
18 -  
19 - operations = [  
20 - migrations.AddField(  
21 - model_name='answersstudent',  
22 - name='student',  
23 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundent', to=settings.AUTH_USER_MODEL, verbose_name='Student'),  
24 - ),  
25 - migrations.AddField(  
26 - model_name='answer',  
27 - name='poll',  
28 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='poll.Poll', verbose_name='Answers'),  
29 - ),  
30 - ]  
poll/migrations/0002_auto_20161117_0217.py 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-17 05:17
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + initial = True
  13 +
  14 + dependencies = [
  15 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  16 + ('poll', '0001_initial'),
  17 + ]
  18 +
  19 + operations = [
  20 + migrations.AddField(
  21 + model_name='answersstudent',
  22 + name='student',
  23 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundent', to=settings.AUTH_USER_MODEL, verbose_name='Student'),
  24 + ),
  25 + migrations.AddField(
  26 + model_name='answer',
  27 + name='poll',
  28 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='poll.Poll', verbose_name='Answers'),
  29 + ),
  30 + ]
users/locale/pt_BR/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid &quot;&quot; @@ -8,7 +8,7 @@ msgid &quot;&quot;
8 msgstr "" 8 msgstr ""
9 "Project-Id-Version: PACKAGE VERSION\n" 9 "Project-Id-Version: PACKAGE VERSION\n"
10 "Report-Msgid-Bugs-To: \n" 10 "Report-Msgid-Bugs-To: \n"
11 -"POT-Creation-Date: 2016-10-26 14:47-0300\n" 11 +"POT-Creation-Date: 2016-11-17 09:46-0300\n"
12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 "Language-Team: LANGUAGE <LL@li.org>\n" 14 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,19 +18,19 @@ msgstr &quot;&quot; @@ -18,19 +18,19 @@ msgstr &quot;&quot;
18 "Content-Transfer-Encoding: 8bit\n" 18 "Content-Transfer-Encoding: 8bit\n"
19 "Plural-Forms: nplurals=2; plural=(n > 1);\n" 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20
21 -#: users/forms.py:60 21 +#: .\forms.py:60
22 msgid "Please enter a valid CPF" 22 msgid "Please enter a valid CPF"
23 msgstr "Por favor, insira um CPF válido" 23 msgstr "Por favor, insira um CPF válido"
24 24
25 -#: users/forms.py:67 25 +#: .\forms.py:66
26 msgid "Please enter a valid date" 26 msgid "Please enter a valid date"
27 msgstr "Por favor, insira uma data válida" 27 msgstr "Por favor, insira uma data válida"
28 28
29 -#: users/models.py:11 users/templates/users/profile.html:61 29 +#: .\models.py:11 .\templates\users\profile.html:64
30 msgid "Login" 30 msgid "Login"
31 msgstr "Login" 31 msgstr "Login"
32 32
33 -#: users/models.py:14 33 +#: .\models.py:14
34 msgid "" 34 msgid ""
35 "Type a valid username. This fields should only contain letters, numbers and " 35 "Type a valid username. This fields should only contain letters, numbers and "
36 "the characteres: @/./+/-/_ ." 36 "the characteres: @/./+/-/_ ."
@@ -38,361 +38,359 @@ msgstr &quot;&quot; @@ -38,361 +38,359 @@ msgstr &quot;&quot;
38 "Digite um nome de usuário válido. Esse campo deve conter apenas letras, " 38 "Digite um nome de usuário válido. Esse campo deve conter apenas letras, "
39 "números e os caracteres: @/./+/-/_ ." 39 "números e os caracteres: @/./+/-/_ ."
40 40
41 -#: users/models.py:17 41 +#: .\models.py:17
42 msgid "" 42 msgid ""
43 "A short name that will be used to identify you in the platform and to access " 43 "A short name that will be used to identify you in the platform and to access "
44 "it" 44 "it"
45 msgstr "" 45 msgstr ""
46 "Um nome curto que será usado para se identificar no acesso à plataforma" 46 "Um nome curto que será usado para se identificar no acesso à plataforma"
47 47
48 -#: users/models.py:18 48 +#: .\models.py:18
49 msgid "Mail" 49 msgid "Mail"
50 msgstr "Email" 50 msgstr "Email"
51 51
52 -#: users/models.py:19 users/templates/list_users.html:67 52 +#: .\models.py:19 .\templates\list_users.html:58
  53 +#: .\templates\users\profile.html:60
53 msgid "Name" 54 msgid "Name"
54 msgstr "Nome" 55 msgstr "Nome"
55 56
56 -#: users/models.py:20 57 +#: .\models.py:20
57 msgid "City" 58 msgid "City"
58 msgstr "Cidade" 59 msgstr "Cidade"
59 60
60 -#: users/models.py:21 61 +#: .\models.py:21
61 msgid "State" 62 msgid "State"
62 msgstr "Estado" 63 msgstr "Estado"
63 64
64 -#: users/models.py:22 users/templates/users/profile.html:105 65 +#: .\models.py:22 .\templates\users\profile.html:108
65 msgid "Gender" 66 msgid "Gender"
66 msgstr "Gênero" 67 msgstr "Gênero"
67 68
68 -#: users/models.py:22 69 +#: .\models.py:22
69 msgid "Male" 70 msgid "Male"
70 msgstr "Masculino" 71 msgstr "Masculino"
71 72
72 -#: users/models.py:22 73 +#: .\models.py:22
73 msgid "Female" 74 msgid "Female"
74 msgstr "Feminino" 75 msgstr "Feminino"
75 76
76 -#: users/models.py:23  
77 -msgid "Image"  
78 -msgstr "Imagem" 77 +#: .\models.py:23
  78 +msgid "Photo"
  79 +msgstr "Foto"
79 80
80 -#: users/models.py:24 users/templates/users/profile.html:109 81 +#: .\models.py:24 .\templates\users\profile.html:112
81 msgid "Birth Date" 82 msgid "Birth Date"
82 msgstr "Data de nascimento" 83 msgstr "Data de nascimento"
83 84
84 -#: users/models.py:25 85 +#: .\models.py:25
85 msgid "Phone" 86 msgid "Phone"
86 msgstr "Telefone" 87 msgstr "Telefone"
87 88
88 -#: users/models.py:26  
89 -msgid "Cpf" 89 +#: .\models.py:26 .\templates\users\profile.html:89
  90 +msgid "CPF"
90 msgstr "CPF" 91 msgstr "CPF"
91 92
92 -#: users/models.py:27 93 +#: .\models.py:27
93 msgid "Type" 94 msgid "Type"
94 msgstr "Tipo" 95 msgstr "Tipo"
95 96
96 -#: users/models.py:27 97 +#: .\models.py:27
97 msgid "Professor" 98 msgid "Professor"
98 msgstr "Professor" 99 msgstr "Professor"
99 100
100 -#: users/models.py:27 users/templates/users/profile.html:81 101 +#: .\models.py:27 .\templates\users\profile.html:84
101 msgid "Student" 102 msgid "Student"
102 msgstr "Aluno" 103 msgstr "Aluno"
103 104
104 -#: users/models.py:28 105 +#: .\models.py:28
105 msgid "Titration" 106 msgid "Titration"
106 msgstr "Título" 107 msgstr "Título"
107 108
108 -#: users/models.py:29 109 +#: .\models.py:29
109 msgid "Year of titration" 110 msgid "Year of titration"
110 msgstr "Ano do título" 111 msgstr "Ano do título"
111 112
112 -#: users/models.py:30  
113 -msgid "Institution where he had titration"  
114 -msgstr "Instituição o qual obteve o título" 113 +#: .\models.py:30 .\templates\users\profile.html:128
  114 +msgid "Institution"
  115 +msgstr "Instituição"
115 116
116 -#: users/models.py:31 users/templates/users/profile.html:135 117 +#: .\models.py:31 .\templates\users\profile.html:136
117 msgid "Curriculum" 118 msgid "Curriculum"
118 msgstr "Currículo" 119 msgstr "Currículo"
119 120
120 -#: users/models.py:32 121 +#: .\models.py:32
121 msgid "Create Date" 122 msgid "Create Date"
122 msgstr "Data de criação" 123 msgstr "Data de criação"
123 124
124 -#: users/models.py:33  
125 -msgid "Administrador" 125 +#: .\models.py:33 .\templates\users\index.html:46
  126 +#: .\templates\users\view.html:19
  127 +msgid "Administrator"
126 msgstr "Administrador" 128 msgstr "Administrador"
127 129
128 -#: users/models.py:34 130 +#: .\models.py:34
129 msgid "Active" 131 msgid "Active"
130 msgstr "Ativo" 132 msgstr "Ativo"
131 133
132 -#: users/models.py:42 134 +#: .\models.py:42
133 msgid "User" 135 msgid "User"
134 msgstr "Usuário" 136 msgstr "Usuário"
135 137
136 -#: users/models.py:43 138 +#: .\models.py:43
137 msgid "Users" 139 msgid "Users"
138 msgstr "Usuários" 140 msgstr "Usuários"
139 141
140 -#: users/templates/list_users.html:15 users/templates/users/profile.html:17  
141 -msgid "Menu"  
142 -msgstr "Menu"  
143 -  
144 -#: users/templates/list_users.html:19 users/templates/users/index.html:7  
145 -#: users/templates/users/view.html:7  
146 -msgid "Home"  
147 -msgstr "Início"  
148 -  
149 -#: users/templates/list_users.html:20  
150 -msgid "Add user" 142 +#: .\templates\list_users.html:14 .\templates\users\index.html:13
  143 +#: .\templates\users\profile.html:16
  144 +msgid "Add User"
151 msgstr "Adicionar usuário" 145 msgstr "Adicionar usuário"
152 146
153 -#: users/templates/list_users.html:21  
154 -msgid "Send email"  
155 -msgstr "Enviar e-mail"  
156 -  
157 -#: users/templates/list_users.html:41 147 +#: .\templates\list_users.html:32
158 msgid "Search..." 148 msgid "Search..."
159 msgstr "Pesquisar..." 149 msgstr "Pesquisar..."
160 150
161 -#: users/templates/list_users.html:45  
162 -msgid "Search"  
163 -msgstr "Pesquisar"  
164 -  
165 -#: users/templates/list_users.html:68 151 +#: .\templates\list_users.html:59
166 msgid "Profile" 152 msgid "Profile"
167 msgstr "Perfil" 153 msgstr "Perfil"
168 154
169 -#: users/templates/list_users.html:69 users/templates/users/profile.html:65 155 +#: .\templates\list_users.html:60 .\templates\users\profile.html:68
170 msgid "Email" 156 msgid "Email"
171 msgstr "Email" 157 msgstr "Email"
172 158
173 -#: users/templates/list_users.html:70 159 +#: .\templates\list_users.html:61
174 msgid "Contact" 160 msgid "Contact"
175 msgstr "Contato" 161 msgstr "Contato"
176 162
177 -#: users/templates/list_users.html:72 163 +#: .\templates\list_users.html:63
178 msgid "Edit" 164 msgid "Edit"
179 msgstr "Editar" 165 msgstr "Editar"
180 166
181 -#: users/templates/list_users.html:73 users/templates/list_users.html:91 167 +#: .\templates\list_users.html:64 .\templates\list_users.html:82
182 msgid "Delete" 168 msgid "Delete"
183 msgstr "Apagar" 169 msgstr "Apagar"
184 170
185 -#: users/templates/list_users.html:84 171 +#: .\templates\list_users.html:75
186 msgid "Confirm delete" 172 msgid "Confirm delete"
187 msgstr "Confirmar" 173 msgstr "Confirmar"
188 174
189 -#: users/templates/list_users.html:87 175 +#: .\templates\list_users.html:78
190 msgid "Are you sure you want to delete the user" 176 msgid "Are you sure you want to delete the user"
191 msgstr "Você tem certeza que deseja deletar o usuário" 177 msgstr "Você tem certeza que deseja deletar o usuário"
192 178
193 -#: users/templates/list_users.html:90  
194 -#: users/templates/users/change_password.html:47  
195 -#: users/templates/users/create.html:130  
196 -#: users/templates/users/edit_profile.html:79  
197 -#: users/templates/users/remove_account.html:35  
198 -#: users/templates/users/update.html:83 179 +#: .\templates\list_users.html:81 .\templates\users\change_password.html:47
  180 +#: .\templates\users\create.html:130 .\templates\users\edit_profile.html:102
  181 +#: .\templates\users\remove_account.html:35 .\templates\users\update.html:83
199 msgid "Cancel" 182 msgid "Cancel"
200 msgstr "Cancelar" 183 msgstr "Cancelar"
201 184
202 -#: users/templates/list_users.html:103 users/templates/users/index.html:74 185 +#: .\templates\list_users.html:94 .\templates\users\index.html:64
203 msgid "No users found" 186 msgid "No users found"
204 msgstr "Nenhum usuário encontrado" 187 msgstr "Nenhum usuário encontrado"
205 188
206 -#: users/templates/users/change_password.html:31  
207 -#, fuzzy  
208 -#| msgid "Password" 189 +#: .\templates\users\change_password.html:31
209 msgid "Current Password" 190 msgid "Current Password"
210 -msgstr "Senha" 191 +msgstr "Senha atual"
211 192
212 -#: users/templates/users/change_password.html:35 193 +#: .\templates\users\change_password.html:35
213 #, fuzzy 194 #, fuzzy
214 #| msgid "Password" 195 #| msgid "Password"
215 msgid "New Password" 196 msgid "New Password"
216 msgstr "Senha" 197 msgstr "Senha"
217 198
218 -#: users/templates/users/change_password.html:39 199 +#: .\templates\users\change_password.html:39
219 msgid "Confirmation" 200 msgid "Confirmation"
220 msgstr "Confirmação" 201 msgstr "Confirmação"
221 202
222 -#: users/templates/users/change_password.html:44  
223 -#: users/templates/users/create.html:127  
224 -#: users/templates/users/edit_profile.html:76  
225 -#: users/templates/users/update.html:80 203 +#: .\templates\users\change_password.html:44 .\templates\users\create.html:127
  204 +#: .\templates\users\edit_profile.html:99 .\templates\users\update.html:80
226 msgid "Save" 205 msgid "Save"
227 msgstr "Salvar" 206 msgstr "Salvar"
228 207
229 -#: users/templates/users/create.html:51  
230 -#: users/templates/users/edit_profile.html:39  
231 -#: users/templates/users/update.html:42 208 +#: .\templates\users\create.html:51
232 msgid "Choose your photo..." 209 msgid "Choose your photo..."
233 msgstr "Envie sua foto..." 210 msgstr "Envie sua foto..."
234 211
235 -#: users/templates/users/create.html:67 212 +#: .\templates\users\create.html:67 .\templates\users\edit_profile.html:47
  213 +#: .\templates\users\update.html:42
236 msgid "Choose your file..." 214 msgid "Choose your file..."
237 -msgstr "Envie um arquivo..."  
238 -  
239 -#: users/templates/users/index.html:8  
240 -msgid "Manage Users"  
241 -msgstr "Gerenciar Usuários"  
242 -  
243 -#: users/templates/users/index.html:15 users/templates/users/view.html:15  
244 -msgid "System Users"  
245 -msgstr "Usuários do sistema"  
246 -  
247 -#: users/templates/users/index.html:18 users/templates/users/view.html:18  
248 -msgid "New Account"  
249 -msgstr "Nova conta" 215 +msgstr "Escolha o arquivo..."
250 216
251 -#: users/templates/users/index.html:21 users/templates/users/view.html:27  
252 -msgid "Send Mail"  
253 -msgstr "Enviar email"  
254 -  
255 -#: users/templates/users/index.html:56 users/templates/users/view.html:39  
256 -msgid "Administrator"  
257 -msgstr "Administrador"  
258 -  
259 -#: users/templates/users/profile.html:21  
260 -#, fuzzy  
261 -#| msgid "Home"  
262 -msgid "Home page" 217 +#: .\templates\users\index.html:7 .\templates\users\view.html:7
  218 +msgid "Home"
263 msgstr "Início" 219 msgstr "Início"
264 220
265 -#: users/templates/users/profile.html:22  
266 -#, fuzzy  
267 -#| msgid "Edit Profile"  
268 -msgid "View Profile"  
269 -msgstr "Editar perfil"  
270 -  
271 -#: users/templates/users/profile.html:23  
272 -msgid "Edit Profile"  
273 -msgstr "Editar perfil"  
274 -  
275 -#: users/templates/users/profile.html:24  
276 -#, fuzzy  
277 -#| msgid "Password"  
278 -msgid "Change Password"  
279 -msgstr "Senha"  
280 -  
281 -#: users/templates/users/profile.html:25  
282 -#, fuzzy  
283 -#| msgid "New Account"  
284 -msgid "Remove account"  
285 -msgstr "Nova conta" 221 +#: .\templates\users\index.html:8
  222 +msgid "Manage Users"
  223 +msgstr "Gerenciar Usuários"
286 224
287 -#: users/templates/users/profile.html:53 225 +#: .\templates\users\profile.html:51
288 #, fuzzy 226 #, fuzzy
289 #| msgid "State" 227 #| msgid "State"
290 msgid "Status" 228 msgid "Status"
291 msgstr "Estado" 229 msgstr "Estado"
292 230
293 -#: users/templates/users/profile.html:77 231 +#: .\templates\users\profile.html:53
  232 +msgid "Online"
  233 +msgstr "Conectado"
  234 +
  235 +#: .\templates\users\profile.html:55
  236 +msgid "OffLine"
  237 +msgstr "Desconectado"
  238 +
  239 +#: .\templates\users\profile.html:80
294 msgid "User role" 240 msgid "User role"
295 msgstr "Tipo de usuário" 241 msgstr "Tipo de usuário"
296 242
297 -#: users/templates/users/profile.html:79 243 +#: .\templates\users\profile.html:82
298 msgid "Teacher" 244 msgid "Teacher"
299 msgstr "Professor" 245 msgstr "Professor"
300 246
301 -#: users/templates/users/profile.html:86  
302 -msgid "CPF"  
303 -msgstr "CPF"  
304 -  
305 -#: users/templates/users/profile.html:91  
306 -msgid "doesn't posssess CPF" 247 +#: .\templates\users\profile.html:94
  248 +#, fuzzy
  249 +#| msgid "doesn't posssess CPF"
  250 +msgid "doesn't possess CPF"
307 msgstr "Não possui CPF" 251 msgstr "Não possui CPF"
308 252
309 -#: users/templates/users/profile.html:96 253 +#: .\templates\users\profile.html:99
310 msgid "Phone Number" 254 msgid "Phone Number"
311 msgstr "Telefone" 255 msgstr "Telefone"
312 256
313 -#: users/templates/users/profile.html:100  
314 -msgid "doesn't posssess Phone" 257 +#: .\templates\users\profile.html:103
  258 +#, fuzzy
  259 +#| msgid "doesn't posssess Phone"
  260 +msgid "doesn't possess Phone"
315 msgstr "Não possui telefone" 261 msgstr "Não possui telefone"
316 262
317 -#: users/templates/users/profile.html:113 263 +#: .\templates\users\profile.html:116
318 msgid "State and City" 264 msgid "State and City"
319 msgstr "Estado e cidade" 265 msgstr "Estado e cidade"
320 266
321 -#: users/templates/users/profile.html:117 267 +#: .\templates\users\profile.html:120
322 msgid "Title" 268 msgid "Title"
323 msgstr "Título" 269 msgstr "Título"
324 270
325 -#: users/templates/users/profile.html:121 271 +#: .\templates\users\profile.html:124
326 msgid "Year" 272 msgid "Year"
327 msgstr "Ano" 273 msgstr "Ano"
328 274
329 -#: users/templates/users/profile.html:125  
330 -msgid "Institution"  
331 -msgstr "Instituição"  
332 -  
333 -#: users/templates/users/profile.html:129 275 +#: .\templates\users\profile.html:132
334 msgid "Didn't inform institution" 276 msgid "Didn't inform institution"
335 msgstr "Não informou a instituição" 277 msgstr "Não informou a instituição"
336 278
337 -#: users/templates/users/profile.html:139 279 +#: .\templates\users\profile.html:142
338 msgid "Didn't upload any curriculum" 280 msgid "Didn't upload any curriculum"
339 msgstr "Não enviou nenhum currículo" 281 msgstr "Não enviou nenhum currículo"
340 282
341 -#: users/templates/users/remove_account.html:28 283 +#: .\templates\users\remove_account.html:28
342 msgid "Are you sure you want delete this account?" 284 msgid "Are you sure you want delete this account?"
343 msgstr "Voce tem certeza que deseja remover esta conta?" 285 msgstr "Voce tem certeza que deseja remover esta conta?"
344 286
345 -#: users/templates/users/remove_account.html:29  
346 -msgid ""  
347 -"All data will be lost and havent how recover it."  
348 -msgstr "Todos os seus dados serão removidos e não haverá como recupera-los posteriormente." 287 +#: .\templates\users\remove_account.html:29
  288 +msgid "All data will be lost and havent how recover it."
  289 +msgstr ""
  290 +"Todos os seus dados serão removidos e não haverá como recupera-los "
  291 +"posteriormente."
349 292
350 -#: users/templates/users/remove_account.html:32 293 +#: .\templates\users\remove_account.html:32
351 msgid "Remove" 294 msgid "Remove"
352 msgstr "Remover" 295 msgstr "Remover"
353 296
354 -#: users/templates/users/view.html:21  
355 -msgid "View User Account"  
356 -msgstr "Visualizar perfil"  
357 -  
358 -#: users/templates/users/view.html:24  
359 -msgid "Edit User Account"  
360 -msgstr "Editar perfil" 297 +#: .\templates\users\search.html:131
  298 +msgid "poll"
  299 +msgstr ""
361 300
362 -#: users/templates/users/view.html:43 301 +#: .\templates\users\view.html:23
363 msgid "Mail:" 302 msgid "Mail:"
364 msgstr "E-mail" 303 msgstr "E-mail"
365 304
366 -#: users/templates/users/view.html:46 305 +#: .\templates\users\view.html:26
367 msgid "Phone:" 306 msgid "Phone:"
368 msgstr "Telefone" 307 msgstr "Telefone"
369 308
370 -#: users/templates/users/view.html:49 309 +#: .\templates\users\view.html:29
371 msgid "Cpf:" 310 msgid "Cpf:"
372 msgstr "CPF" 311 msgstr "CPF"
373 312
374 -#: users/templates/users/view.html:52 313 +#: .\templates\users\view.html:32
375 msgid "Birth date:" 314 msgid "Birth date:"
376 msgstr "Data de nascimento:" 315 msgstr "Data de nascimento:"
377 316
378 -#: users/views.py:55 317 +#: .\views.py:70
379 msgid "User created successfully!" 318 msgid "User created successfully!"
380 msgstr "Usuário criado com sucesso!" 319 msgstr "Usuário criado com sucesso!"
381 320
382 -#: users/views.py:84 321 +#: .\views.py:99
383 msgid "User edited successfully!" 322 msgid "User edited successfully!"
384 msgstr "Usuário editado com sucesso!" 323 msgstr "Usuário editado com sucesso!"
385 324
386 -#: users/views.py:101 325 +#: .\views.py:116 .\views.py:122
387 #, fuzzy 326 #, fuzzy
388 #| msgid "User edited successfully!" 327 #| msgid "User edited successfully!"
389 msgid "User deleted Successfully!" 328 msgid "User deleted Successfully!"
390 msgstr "Usuário editado com sucesso!" 329 msgstr "Usuário editado com sucesso!"
391 330
392 -#: users/views.py:126 331 +#: .\views.py:152
393 msgid "Profile edited successfully!" 332 msgid "Profile edited successfully!"
394 msgstr "Perfil editado com sucesso!" 333 msgstr "Perfil editado com sucesso!"
395 334
  335 +#~ msgid "Administrador"
  336 +#~ msgstr "Administrador"
  337 +
  338 +#~ msgid "Image"
  339 +#~ msgstr "Imagem"
  340 +
  341 +#~ msgid "Cpf"
  342 +#~ msgstr "CPF"
  343 +
  344 +#~ msgid "Institution where he had titration"
  345 +#~ msgstr "Instituição o qual obteve o título"
  346 +
  347 +#~ msgid "Menu"
  348 +#~ msgstr "Menu"
  349 +
  350 +#~ msgid "Send email"
  351 +#~ msgstr "Enviar e-mail"
  352 +
  353 +#~ msgid "Search"
  354 +#~ msgstr "Pesquisar"
  355 +
  356 +#~ msgid "System Users"
  357 +#~ msgstr "Usuários do sistema"
  358 +
  359 +#~ msgid "New Account"
  360 +#~ msgstr "Nova conta"
  361 +
  362 +#~ msgid "Send Mail"
  363 +#~ msgstr "Enviar email"
  364 +
  365 +#, fuzzy
  366 +#~| msgid "Home"
  367 +#~ msgid "Home page"
  368 +#~ msgstr "Início"
  369 +
  370 +#, fuzzy
  371 +#~| msgid "Edit Profile"
  372 +#~ msgid "View Profile"
  373 +#~ msgstr "Editar perfil"
  374 +
  375 +#~ msgid "Edit Profile"
  376 +#~ msgstr "Editar perfil"
  377 +
  378 +#, fuzzy
  379 +#~| msgid "Password"
  380 +#~ msgid "Change Password"
  381 +#~ msgstr "Senha"
  382 +
  383 +#, fuzzy
  384 +#~| msgid "New Account"
  385 +#~ msgid "Remove account"
  386 +#~ msgstr "Remover conta"
  387 +
  388 +#~ msgid "View User Account"
  389 +#~ msgstr "Visualizar perfil"
  390 +
  391 +#~ msgid "Edit User Account"
  392 +#~ msgstr "Editar perfil"
  393 +
396 #~ msgid "New User" 394 #~ msgid "New User"
397 #~ msgstr "Novo usuário" 395 #~ msgstr "Novo usuário"
398 396
users/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-16 13:57 2 +# Generated by Django 1.10 on 2016-11-17 05:17
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 import django.contrib.auth.models 5 import django.contrib.auth.models
users/models.py
@@ -30,7 +30,7 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -30,7 +30,7 @@ class User(AbstractBaseUser, PermissionsMixin):
30 institution = models.CharField(_('Institution'), max_length = 50, blank=True, null=True) 30 institution = models.CharField(_('Institution'), max_length = 50, blank=True, null=True)
31 curriculum = models.FileField(verbose_name = _('Curriculum'), upload_to='users/curriculum/', null=True, blank=True) 31 curriculum = models.FileField(verbose_name = _('Curriculum'), upload_to='users/curriculum/', null=True, blank=True)
32 date_created = models.DateTimeField(_('Create Date'), auto_now_add = True) 32 date_created = models.DateTimeField(_('Create Date'), auto_now_add = True)
33 - is_staff = models.BooleanField(_('Administrador'), default = False) 33 + is_staff = models.BooleanField(_('Administrator'), default = False)
34 is_active = models.BooleanField(_('Active'), default = True) 34 is_active = models.BooleanField(_('Active'), default = True)
35 35
36 USERNAME_FIELD = 'username' 36 USERNAME_FIELD = 'username'
users/templates/list_users.html
@@ -10,9 +10,6 @@ @@ -10,9 +10,6 @@
10 {% endblock %} 10 {% endblock %}
11 11
12 {% block menu %} 12 {% block menu %}
13 - {% if user|has_role:'system_admin' %}  
14 - <li> <a href="{% url 'users:create' %}">{% trans 'Add User' %}</a></li>  
15 - {% endif %}  
16 {% endblock %} 13 {% endblock %}
17 14
18 {% block content %} 15 {% block content %}
users/templates/users/create.html
@@ -38,8 +38,8 @@ @@ -38,8 +38,8 @@
38 {% else %} 38 {% else %}
39 <label for="{{ field.auto_id }}">{{ field.label }}</label> 39 <label for="{{ field.auto_id }}">{{ field.label }}</label>
40 {% endif %} 40 {% endif %}
41 - <input type="text" class="form-control input-sm date-picker" name="{{field.name}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">  
42 41
  42 + {% render_field field class='form-control date-picker' %}
43 {% elif field.auto_id == 'id_image' %} 43 {% elif field.auto_id == 'id_image' %}
44 {% if field.field.required %} 44 {% if field.field.required %}
45 <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label> 45 <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>
@@ -71,10 +71,10 @@ @@ -71,10 +71,10 @@
71 </button> 71 </button>
72 </span> 72 </span>
73 </div> 73 </div>
74 - {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %} 74 + {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %}
75 <div class="checkbox"> 75 <div class="checkbox">
76 <label for="{{ field.auto_id }}"> 76 <label for="{{ field.auto_id }}">
77 - {% render_field field %}<span class="checkbox-material"><span class="check"></span></span> {{field.label}} 77 + {% render_field field %} {{field.label}}
78 </label> 78 </label>
79 </div> 79 </div>
80 {% elif field.auto_id == 'id_cpf' %} 80 {% elif field.auto_id == 'id_cpf' %}
@@ -123,10 +123,10 @@ @@ -123,10 +123,10 @@
123 {% endif %} 123 {% endif %}
124 </div> 124 </div>
125 {% endfor %} 125 {% endfor %}
126 - <div class="col-md-offset-2 col-md-2 col-sm-2 col-xs-2"> 126 + <div class="col-md-5 col-xs-6 col-sm-6 col-lg-5 text-center">
127 <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-success" onclick="validarCpfSemAlert(id_cpf, CPF, idElementoMensagemErro)'" /> 127 <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-success" onclick="validarCpfSemAlert(id_cpf, CPF, idElementoMensagemErro)'" />
128 </div> 128 </div>
129 - <div class="col-md-offset-4 col-md-2 col-sm-2 col-xs-2"> 129 + <div class="col-md-5 col-xs-6 col-sm-6 col-lg-5 text-center">
130 <a href="{% url 'users:manage' %}" class="btn btn-raised btn-danger" >{% trans 'Cancel' %}</a> 130 <a href="{% url 'users:manage' %}" class="btn btn-raised btn-danger" >{% trans 'Cancel' %}</a>
131 </div> 131 </div>
132 </form> 132 </form>
@@ -136,4 +136,11 @@ @@ -136,4 +136,11 @@
136 </br> 136 </br>
137 </br> 137 </br>
138 </br> 138 </br>
  139 +<script type="text/javascript">
  140 +var locale = navigator.language || navigator.userLanguage;
  141 +
  142 +$('.date-picker').datepicker({
  143 + language: locale,
  144 +});
  145 +</script>
139 {% endblock %} 146 {% endblock %}
users/templates/users/index.html
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 {% endblock %} 10 {% endblock %}
11 11
12 {% block menu %} 12 {% block menu %}
13 - <li> <a href="{% url 'users:create' %}">{% trans 'Add User' %}</a></li> 13 +
14 {% endblock %} 14 {% endblock %}
15 15
16 {% block content %} 16 {% block content %}
users/views.py
@@ -39,7 +39,7 @@ class UsersListView(HasRoleMixin, LoginRequiredMixin, generic.ListView): @@ -39,7 +39,7 @@ class UsersListView(HasRoleMixin, LoginRequiredMixin, generic.ListView):
39 search = self.request.GET.get('search', None) 39 search = self.request.GET.get('search', None)
40 40
41 if search is None: 41 if search is None:
42 - users = User.objects.exclude(username = self.request.user.username) 42 + users = User.objects.all().order_by('name').exclude( username = self.request.user.username)
43 else: 43 else:
44 users = User.objects.filter(Q(username = search) | Q(name = search) | Q(name__icontains = search) | Q(username__icontains = search)).exclude( username = self.request.user.username) 44 users = User.objects.filter(Q(username = search) | Q(name = search) | Q(name__icontains = search) | Q(username__icontains = search)).exclude( username = self.request.user.username)
45 45
@@ -67,9 +67,13 @@ class Create(HasRoleMixin, LoginRequiredMixin, generic.edit.CreateView): @@ -67,9 +67,13 @@ class Create(HasRoleMixin, LoginRequiredMixin, generic.edit.CreateView):
67 67
68 self.object.save() 68 self.object.save()
69 69
70 - messages.success(self.request, _('User created successfully!')) 70 + messages.success(self.request, _('User ')+self.object.name+(' created successfully!'))
71 71
72 return super(Create, self).form_valid(form) 72 return super(Create, self).form_valid(form)
  73 + def get_context_data (self, **kwargs):
  74 + context = super(Create, self).get_context_data(**kwargs)
  75 + context['title'] = _("Add User")
  76 + return context
73 77
74 class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView): 78 class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView):
75 79
@@ -96,7 +100,7 @@ class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView): @@ -96,7 +100,7 @@ class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView):
96 100
97 self.object.save() 101 self.object.save()
98 102
99 - messages.success(self.request, _('User edited successfully!')) 103 + messages.success(self.request, _('User ')+self.object.name+(' updated successfully!'))
100 104
101 return super(Update, self).form_valid(form) 105 return super(Update, self).form_valid(form)
102 106
@@ -243,4 +247,3 @@ class UserViewSet(viewsets.ModelViewSet): @@ -243,4 +247,3 @@ class UserViewSet(viewsets.ModelViewSet):
243 queryset = User.objects.all() 247 queryset = User.objects.all()
244 serializer_class = UserSerializer 248 serializer_class = UserSerializer
245 permissions_classes = (IsAuthenticatedOrReadOnly,) 249 permissions_classes = (IsAuthenticatedOrReadOnly,)
246 -