Commit 2c886a7e73484e4896856c8e59bcc09ae8ca4fe6
Exists in
master
and in
5 other branches
Merge
Showing
59 changed files
with
1036 additions
and
848 deletions
Show diff stats
amadeus/urls.py
... | ... | @@ -23,6 +23,7 @@ urlpatterns = [ |
23 | 23 | url(r'^home/', include('app.urls', namespace = 'app')), |
24 | 24 | url(r'^courses/', include('courses.urls', namespace = 'course')), |
25 | 25 | url(r'^users/', include('users.urls', namespace = 'users')), |
26 | + url(r'^exercise/', include('exercise.urls', namespace = 'exercise')), | |
26 | 27 | url(r'^admin/', admin.site.urls), |
27 | 28 | url(r'^', include('core.urls', namespace = 'core')), |
28 | 29 | #API | ... | ... |
app/migrations/0001_initial.py
app/templates/home.html
... | ... | @@ -96,8 +96,26 @@ |
96 | 96 | |
97 | 97 | {% endblock %} |
98 | 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 | 119 | {% endif %} |
102 | 120 | </ul> |
103 | 121 | </div> | ... | ... |
core/locale/pt_BR/LC_MESSAGES/django.po
... | ... | @@ -8,7 +8,7 @@ msgid "" |
8 | 8 | msgstr "" |
9 | 9 | "Project-Id-Version: PACKAGE VERSION\n" |
10 | 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 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
13 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
14 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | @@ -23,10 +23,8 @@ msgid "Password" |
23 | 23 | msgstr "Senha" |
24 | 24 | |
25 | 25 | #: .\forms.py:13 |
26 | -#, fuzzy | |
27 | -#| msgid "Confirm password:" | |
28 | 26 | msgid "Confirm Password" |
29 | -msgstr "Confirmação de senha:" | |
27 | +msgstr "Confirme a senha:" | |
30 | 28 | |
31 | 29 | #: .\forms.py:27 |
32 | 30 | msgid "There is already a registered User with this e-mail" |
... | ... | @@ -40,7 +38,7 @@ msgstr "Por favor, insira uma data válida" |
40 | 38 | #, fuzzy |
41 | 39 | #| msgid "There is already a registeres User with this CPF" |
42 | 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 | 43 | #: .\forms.py:52 |
46 | 44 | #, python-format |
... | ... | @@ -138,7 +136,7 @@ msgstr "Autor" |
138 | 136 | msgid "Notification" |
139 | 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 | 140 | msgid "Notifications" |
143 | 141 | msgstr "Notificações" |
144 | 142 | |
... | ... | @@ -166,11 +164,11 @@ msgstr "Logs" |
166 | 164 | msgid "Search Files (.pdf, others) and/or activities" |
167 | 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 | 168 | msgid "See More" |
171 | 169 | msgstr "Ver Mais" |
172 | 170 | |
173 | -#: .\templates\base.html:105 .\templates\guest.html:83 | |
171 | +#: .\templates\base.html:105 | |
174 | 172 | msgid "messages" |
175 | 173 | msgstr "Mensagens" |
176 | 174 | |
... | ... | @@ -196,14 +194,22 @@ msgstr "Mudar senha" |
196 | 194 | msgid "Remove account" |
197 | 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 | 202 | msgid "Menu" |
201 | 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 | 206 | msgid "Register" |
205 | 207 | msgstr "Cadastrar" |
206 | 208 | |
209 | +#: .\templates\guest.html:98 | |
210 | +msgid "Search Courses" | |
211 | +msgstr "Pesquisar Cursos" | |
212 | + | |
207 | 213 | #: .\templates\index.html:37 |
208 | 214 | msgid "Sign in with your account to continue" |
209 | 215 | msgstr "Faça login com sua conta para continuar" |
... | ... | @@ -220,10 +226,6 @@ msgstr "Lembrar E-mail" |
220 | 226 | msgid "Log in" |
221 | 227 | msgstr "Acessar" |
222 | 228 | |
223 | -#: .\templates\index.html:67 | |
224 | -msgid "Guest" | |
225 | -msgstr "Convidado" | |
226 | - | |
227 | 229 | #: .\templates\index.html:72 |
228 | 230 | msgid "Forgot your password?" |
229 | 231 | msgstr "Esqueceu sua senha?" |
... | ... | @@ -236,9 +238,11 @@ msgstr "Cadastrar" |
236 | 238 | msgid "User Register" |
237 | 239 | msgstr "Cadastro de usuário" |
238 | 240 | |
241 | +#: .\templates\register_user.html:61 | |
242 | +msgid "Choose your photo..." | |
243 | +msgstr "" | |
244 | + | |
239 | 245 | #: .\templates\register_user.html:71 |
240 | -#, fuzzy | |
241 | -#| msgid "Chose your file ..." | |
242 | 246 | msgid "Choose the file ..." |
243 | 247 | msgstr "Escolha o arquivo..." |
244 | 248 | |
... | ... | @@ -249,7 +253,7 @@ msgstr "Entrar" |
249 | 253 | |
250 | 254 | #: .\templates\registration\passwor_reset_complete.html:19 |
251 | 255 | msgid "Your password was reseted successful" |
252 | -msgstr "" | |
256 | +msgstr "Sua senha foi resetada com sucesso" | |
253 | 257 | |
254 | 258 | #: .\templates\registration\passwor_reset_confirm.html:19 |
255 | 259 | #: .\templates\registration\passwor_reset_done.html:18 |
... | ... | @@ -389,9 +393,6 @@ msgstr "E-mail ou senha incorretos." |
389 | 393 | #~ msgid "Manage Users" |
390 | 394 | #~ msgstr "Gerenciar usuários" |
391 | 395 | |
392 | -#~ msgid "Manage Courses" | |
393 | -#~ msgstr "Gerenciar cursos" | |
394 | - | |
395 | 396 | #~ msgid "Category" |
396 | 397 | #~ msgstr "Categoria" |
397 | 398 | ... | ... |
core/migrations/0001_initial.py
core/migrations/0002_auto_20161116_1057.py
... | ... | @@ -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 | - ] |
... | ... | @@ -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 | 64 | </div> |
65 | 65 | <div class="navbar-collapse collapse navbar-responsive-collapse"> |
66 | 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 | 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 | 69 | </ul> |
87 | 70 | </div> |
... | ... | @@ -107,21 +90,6 @@ |
107 | 90 | </div> |
108 | 91 | <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"> |
109 | 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 | 93 | {% endblock %} |
126 | 94 | {% block render_breadcrumbs %}{% endblock %} |
127 | 95 | <div> |
... | ... | @@ -137,7 +105,7 @@ |
137 | 105 | <h4 class="panel-title"> |
138 | 106 | <a class="category-course-link" data-toggle="collapse" href="#{{category.slug}}">{{category.name}}</a> |
139 | 107 | </h4> |
140 | - | |
108 | + | |
141 | 109 | </div> |
142 | 110 | <div id="{{category.slug}}" class="panel-collapse collapse"> |
143 | 111 | {% for course in category.course_category.all %} |
... | ... | @@ -150,6 +118,27 @@ |
150 | 118 | </div> |
151 | 119 | {% endfor %} |
152 | 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 | 142 | {% endblock %} |
154 | 143 | </div> |
155 | 144 | </div> |
... | ... | @@ -161,4 +150,4 @@ |
161 | 150 | {% endblock script_file %} |
162 | 151 | </body> |
163 | 152 | |
164 | -</html> | |
165 | 153 | \ No newline at end of file |
154 | +</html> | ... | ... |
core/templates/register_user.html
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | {% elif field.auto_id == 'id_image' %} |
59 | 59 | {% render_field field class='form-control' %} |
60 | 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 | 62 | <span class="input-group-btn input-group-sm"> |
63 | 63 | <button type="button" class="btn btn-fab btn-fab-mini"> |
64 | 64 | <i class="material-icons">image</i> | ... | ... |
core/views.py
... | ... | @@ -14,6 +14,8 @@ from core.mixins import NotificationMixin |
14 | 14 | from .models import Notification, Log |
15 | 15 | from rolepermissions.shortcuts import assign_role |
16 | 16 | from django.contrib.auth.decorators import login_required |
17 | +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger | |
18 | + | |
17 | 19 | #API REST IMPORTS |
18 | 20 | from .serializers import LogSerializer |
19 | 21 | from rest_framework import status, serializers, permissions, viewsets |
... | ... | @@ -103,15 +105,24 @@ class GuestView (ListView): |
103 | 105 | |
104 | 106 | template_name = 'guest.html' |
105 | 107 | context_object_name = 'courses' |
108 | + queryset = CourseCategory.objects.all() | |
106 | 109 | paginate_by = 10 |
107 | 110 | |
108 | - def get_queryset(self): | |
109 | - return Course.objects.filter(public=True) | |
110 | - | |
111 | - | |
112 | 111 | def get_context_data (self, **kwargs): |
113 | 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 | 126 | return context |
116 | 127 | |
117 | 128 | ... | ... |
courses/migrations/0001_initial.py
1 | 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 | 3 | from __future__ import unicode_literals |
4 | 4 | |
5 | 5 | import autoslug.fields |
... | ... | @@ -69,8 +69,8 @@ class Migration(migrations.Migration): |
69 | 69 | ], |
70 | 70 | options={ |
71 | 71 | 'verbose_name_plural': 'Courses', |
72 | - 'ordering': ('create_date', 'name'), | |
73 | 72 | 'verbose_name': 'Course', |
73 | + 'ordering': ('create_date', 'name'), | |
74 | 74 | }, |
75 | 75 | ), |
76 | 76 | migrations.CreateModel( |
... | ... | @@ -128,8 +128,8 @@ class Migration(migrations.Migration): |
128 | 128 | ], |
129 | 129 | options={ |
130 | 130 | 'verbose_name_plural': 'Subjects', |
131 | - 'ordering': ('create_date', 'name'), | |
132 | 131 | 'verbose_name': 'Subject', |
132 | + 'ordering': ('create_date', 'name'), | |
133 | 133 | }, |
134 | 134 | ), |
135 | 135 | migrations.CreateModel( |
... | ... | @@ -160,8 +160,8 @@ class Migration(migrations.Migration): |
160 | 160 | ], |
161 | 161 | options={ |
162 | 162 | 'verbose_name_plural': 'Topics', |
163 | - 'ordering': ('create_date', 'name'), | |
164 | 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 | -# -*- 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 | - ] |
... | ... | @@ -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 | 63 | </ul> |
64 | 64 | </div> |
65 | 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 | 66 | </div> |
94 | 67 | {% endif %} |
95 | 68 | ... | ... |
courses/templates/subject/form_view_teacher.html
... | ... | @@ -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> |
8 | 8 | </div> |
9 | 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 | 11 | <h4>{{topic}}</h4> |
12 | 12 | </a> |
13 | 13 | </div><!--column --> |
... | ... | @@ -21,7 +21,7 @@ |
21 | 21 | {% professor_subject topic.subject user as dropdown_topic %} |
22 | 22 | {% if dropdown_topic %} |
23 | 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> {% 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> {% trans "Replicate" %}</a></li> | |
25 | 25 | <li><a href="javascript:show_editation('{{topic.slug}}')"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans "Edit" %}</a></li> |
26 | 26 | <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeTopic"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans "Remove" %}</a></li> |
27 | 27 | </ul> |
... | ... | @@ -123,23 +123,18 @@ |
123 | 123 | </ul> |
124 | 124 | </div> |
125 | 125 | </div> |
126 | - <div class="col-xs-4 col-md-4"> | |
127 | 126 | <div class="resource_inline"> |
128 | 127 | <h4>{% trans 'Exercises' %}</h4> |
129 | 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 | 137 | </div> |
142 | - </div> | |
143 | 138 | </div> |
144 | 139 | |
145 | 140 | {# opções de cancelar e editar no modo de edição #} | ... | ... |
courses/templates/subject/replicate.html
... | ... | @@ -2,61 +2,51 @@ |
2 | 2 | |
3 | 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 | 5 | {% block content %} |
13 | -<div class="panel panel-default"> | |
6 | + | |
7 | + <div class="panel panel-default"> | |
14 | 8 | <div class="panel-body"> |
15 | 9 | <form class="form-group " method="post" action=""> |
16 | 10 | {% csrf_token %} |
17 | 11 | |
18 | 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 | 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 | 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 | 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 | 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 | 45 | </div> |
54 | - | |
55 | 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 | 48 | </div> |
58 | 49 | </form> |
59 | - | |
60 | 50 | </div> |
61 | 51 | </div> |
62 | 52 | |
... | ... | @@ -70,4 +60,4 @@ |
70 | 60 | $('#id_description').summernote({height: 300}); |
71 | 61 | }); |
72 | 62 | </script> |
73 | -{% endblock %} | |
74 | 63 | \ No newline at end of file |
64 | +{% endblock content %} | ... | ... |
courses/templates/topic/index.html
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | </div> |
66 | 66 | <div class="panel panel-default"> |
67 | 67 | <div class="panel-body"> |
68 | - {% include "topic/topic_card_student.html" %} | |
68 | + {% include "topic/topic_card.html" %} | |
69 | 69 | {% comment %} |
70 | 70 | |
71 | 71 | |
... | ... | @@ -116,13 +116,23 @@ |
116 | 116 | </fieldset> |
117 | 117 | </form>--> |
118 | 118 | {% endcomment %} |
119 | - | |
120 | - | |
121 | - | |
122 | - | |
123 | 119 | </div> |
124 | - | |
125 | - | |
126 | 120 | </div> |
127 | 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 | 138 | {% endblock %} | ... | ... |
... | ... | @@ -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 | -{% 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 %} |
... | ... | @@ -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 | 29 | \ No newline at end of file | ... | ... |
courses/templates/topic/topic_card_student.html
... | ... | @@ -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 | 6 | url(r'^all-courses/$', views.AllCoursesView.as_view(), name='all_courses'), |
7 | 7 | url(r'^create/$', views.CreateCourseView.as_view(), name='create'), |
8 | 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 | 9 | url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'), |
11 | 10 | url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'), |
12 | 11 | url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_course, name='subscribe'), |
... | ... | @@ -19,10 +18,11 @@ urlpatterns = [ |
19 | 18 | url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), |
20 | 19 | url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'), |
21 | 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 | 22 | url(r'^subjects/subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_subject, name='subscribe_subject'), |
23 | 23 | url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'), |
24 | 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 | 26 | url(r'^topics/replicate/(?P<slug>[\w_-]+)/$', views.ReplicateTopicView.as_view(), name='replicate_topic'), |
27 | 27 | url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'), |
28 | 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 | 56 | if (cat): |
57 | 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 | 61 | class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): |
62 | 62 | |
... | ... | @@ -93,10 +93,10 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): |
93 | 93 | list_courses = self.get_queryset().order_by('name') |
94 | 94 | # categorys_courses = CourseCategory.objects.all() |
95 | 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 | 97 | # categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct() |
98 | 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 | 101 | context['categorys_courses'] = course_category(list_courses) |
102 | 102 | return context |
... | ... | @@ -136,6 +136,7 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView): |
136 | 136 | list_courses = self.get_queryset() |
137 | 137 | |
138 | 138 | context['categorys_courses'] = course_category(list_courses) |
139 | + | |
139 | 140 | return context |
140 | 141 | |
141 | 142 | class CreateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView): |
... | ... | @@ -561,39 +562,6 @@ class SubjectsView(LoginRequiredMixin, LogMixin, generic.ListView): |
561 | 562 | context['files'] = TopicFile.objects.filter(students__name = self.request.user.name) |
562 | 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 | 566 | class UploadMaterialView(LoginRequiredMixin, generic.edit.CreateView): |
599 | 567 | login_url = reverse_lazy("core:home") |
... | ... | @@ -663,6 +631,11 @@ class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView): |
663 | 631 | activitys = Activity.objects.filter(topic__name = topic.name) |
664 | 632 | students_activit = User.objects.filter(activities__in = Activity.objects.all()) |
665 | 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 | 640 | context['topic'] = topic |
668 | 641 | context['subject'] = topic.subject |
... | ... | @@ -1017,13 +990,13 @@ class TopicViewSet(viewsets.ModelViewSet): |
1017 | 990 | class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin,generic.edit.CreateView): |
1018 | 991 | log_component = "course" |
1019 | 992 | log_resource = "topic" |
1020 | - log_action = "create" | |
993 | + log_action = "replicate" | |
1021 | 994 | log_context = {} |
1022 | 995 | |
1023 | 996 | allowed_roles = ['professor', 'system_admin'] |
1024 | 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 | 1000 | form_class = TopicForm |
1028 | 1001 | |
1029 | 1002 | def get_success_url(self): |
... | ... | @@ -1032,21 +1005,23 @@ class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, Notificati |
1032 | 1005 | def get_context_data(self, **kwargs): |
1033 | 1006 | context = super(ReplicateTopicView, self).get_context_data(**kwargs) |
1034 | 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 | 1009 | context['course'] = subject.course |
1037 | 1010 | context['subject'] = subject |
1038 | 1011 | context['subjects'] = subject.course.subjects.all() |
1039 | 1012 | context['topic'] = topic |
1040 | 1013 | return context |
1041 | 1014 | |
1042 | - | |
1043 | 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 | 1019 | self.object = form.save(commit = False) |
1020 | + self.object.topic = topic | |
1021 | + self.object.subject = subject | |
1046 | 1022 | self.object.owner = self.request.user |
1047 | 1023 | self.object.save() |
1048 | - | |
1049 | - action = super(ReplicateTopicView, self).createorRetrieveAction("replicate Topic") | |
1024 | + action = super(ReplicateTopicView, self).createorRetrieveAction("create Topic") | |
1050 | 1025 | super(ReplicateTopicView, self).createNotification("Topic "+ self.object.name + " was created", |
1051 | 1026 | resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]), |
1052 | 1027 | actor=self.request.user, users = self.object.subject.course.students.all() ) |
... | ... | @@ -1066,3 +1041,55 @@ class ReplicateTopicView (LoginRequiredMixin, HasRoleMixin, LogMixin, Notificati |
1066 | 1041 | super(ReplicateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
1067 | 1042 | |
1068 | 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 | 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 | 3 | from __future__ import unicode_literals |
4 | 4 | |
5 | 5 | from django.db import migrations, models |
... | ... | @@ -24,8 +24,8 @@ class Migration(migrations.Migration): |
24 | 24 | ], |
25 | 25 | options={ |
26 | 26 | 'verbose_name_plural': 'Answers', |
27 | - 'ordering': ('order',), | |
28 | 27 | 'verbose_name': 'Answer', |
28 | + 'ordering': ('order',), | |
29 | 29 | }, |
30 | 30 | ), |
31 | 31 | migrations.CreateModel( | ... | ... |
exam/migrations/0002_auto_20161116_1057.py
... | ... | @@ -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 | - ] |
... | ... | @@ -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 | 2 | from .models import Exercise |
3 | 3 | |
4 | 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 | 8 | admin.site.register(Exercise, ExerciseAdmin) | ... | ... |
exercise/forms.py
... | ... | @@ -9,11 +9,13 @@ class ExerciseForm(forms.ModelForm): |
9 | 9 | |
10 | 10 | class Meta: |
11 | 11 | model = Exercise |
12 | - fields = ['name', 'file'] | |
12 | + fields = ['name_exercise', 'description', 'init_date', | |
13 | + 'end_date', 'file'] | |
13 | 14 | |
14 | 15 | |
15 | 16 | class UpdateExerciseForm(forms.ModelForm): |
16 | 17 | |
17 | 18 | class Meta: |
18 | 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 | 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 | 3 | from __future__ import unicode_literals |
4 | 4 | |
5 | +from decimal import Decimal | |
6 | +from django.conf import settings | |
5 | 7 | from django.db import migrations, models |
6 | 8 | import django.db.models.deletion |
9 | +import exercise.models | |
7 | 10 | |
8 | 11 | |
9 | 12 | class Migration(migrations.Migration): |
... | ... | @@ -11,7 +14,9 @@ class Migration(migrations.Migration): |
11 | 14 | initial = True |
12 | 15 | |
13 | 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 | 22 | operations = [ |
... | ... | @@ -19,8 +24,15 @@ class Migration(migrations.Migration): |
19 | 24 | name='Exercise', |
20 | 25 | fields=[ |
21 | 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 | 36 | ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='courses.Topic', verbose_name='Topic')), |
25 | 37 | ], |
26 | 38 | ), | ... | ... |
... | ... | @@ -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 | + ] | ... | ... |
... | ... | @@ -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 | 1 | from courses.models import Topic |
2 | +from decimal import Decimal | |
3 | +from django.db import models | |
3 | 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 | 9 | Function to return the path where the file should be saved |
... | ... | @@ -17,6 +20,17 @@ It represents the Exercises inside topic. |
17 | 20 | |
18 | 21 | |
19 | 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 | 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 | 37 | \ No newline at end of file | ... | ... |
exercise/static/js/exercise.js
... | ... | @@ -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 | 65 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | 61 | \ No newline at end of file | ... | ... |
exercise/templates/exercise/create_exercise.html
... | ... | @@ -9,75 +9,104 @@ |
9 | 9 | </div> |
10 | 10 | <div class="modal-body"> |
11 | 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 | 13 | {% csrf_token %} |
14 | 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">×</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">×</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 | 40 | </button> |
20 | - <p>{{ message }}</p> | |
41 | + </span> | |
21 | 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 | 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">×</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">×</span> | |
53 | + </button> | |
54 | + <ul> | |
55 | + {% for error in field.errors %} | |
56 | + <li>{{ error }}</li> | |
57 | + {% endfor %} | |
58 | + </ul> | |
59 | + </div> | |
41 | 60 | {% endif %} |
42 | 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 | 82 | </div> |
53 | 83 | <!-- EndModal --> |
54 | -<script src="{% static 'js/exercises.js' %}"></script> | |
55 | 84 | <script type="text/javascript"> |
56 | 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 | 112 | </script> | ... | ... |
exercise/templates/exercise/exercise_edit.html
1 | 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 | 3 | {% for exercise in exercises %} |
4 | 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 | 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/templatetags/list_topic_exercises.py
... | ... | @@ -5,21 +5,21 @@ register = template.Library() |
5 | 5 | |
6 | 6 | |
7 | 7 | @register.inclusion_tag('exercise/exercise_list.html') |
8 | -def list_topic_exercise(request): | |
8 | +def list_topic_exercise(request, topic): | |
9 | 9 | context = { |
10 | 10 | 'request': request, |
11 | 11 | } |
12 | - context['exercises'] = Exercise.objects.all() | |
12 | + context['exercises'] = Exercise.objects.filter(topic=topic) | |
13 | 13 | |
14 | 14 | return context |
15 | 15 | |
16 | 16 | |
17 | 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 | 19 | context = { |
20 | 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 | 25 | return context | ... | ... |
exercise/views.py
1 | 1 | from .forms import ExerciseForm, UpdateExerciseForm |
2 | 2 | from .models import Exercise |
3 | -from files.utils import mime_type_to_material_icons | |
4 | 3 | from core.decorators import log_decorator |
5 | 4 | from core.mixins import LogMixin, NotificationMixin |
6 | 5 | from core.models import Log, MimeType |
... | ... | @@ -13,8 +12,10 @@ from django.core.urlresolvers import reverse_lazy |
13 | 12 | from django.shortcuts import render, get_object_or_404, redirect |
14 | 13 | from django.urls import reverse |
15 | 14 | from django.views import generic |
15 | +from files.utils import mime_type_to_material_icons | |
16 | 16 | from rolepermissions.mixins import HasRoleMixin |
17 | 17 | from rolepermissions.verifications import has_role |
18 | +from users.models import User | |
18 | 19 | |
19 | 20 | |
20 | 21 | class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView): |
... | ... | @@ -23,7 +24,7 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
23 | 24 | log_action = 'create' |
24 | 25 | log_component = {} |
25 | 26 | |
26 | - allowed_roles = ['student'] | |
27 | + allowed_roles = ['professor', 'student'] | |
27 | 28 | login_url = reverse_lazy("core:home") |
28 | 29 | redirect_field_name = 'next' |
29 | 30 | model = Exercise |
... | ... | @@ -35,7 +36,6 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
35 | 36 | log_resource = "exercise" |
36 | 37 | log_action = "create" |
37 | 38 | log_context = {} |
38 | - context_object_name = 'form' | |
39 | 39 | |
40 | 40 | def form_invalid(self, form, **kwargs): |
41 | 41 | context = super(CreateExercise, self).form_invalid(form) |
... | ... | @@ -47,19 +47,16 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
47 | 47 | self.object = form.save(commit = False) |
48 | 48 | topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) |
49 | 49 | self.object.topic = topic |
50 | - | |
51 | - self.object.name = str(self.object) | |
52 | - | |
53 | 50 | |
54 | 51 | # Set MimeType |
55 | - exercise = self.request.FILES['exercise_url'] | |
52 | + exercise = self.request.FILES['file'] | |
56 | 53 | try: |
57 | 54 | if exercise: |
58 | 55 | exercise_type = exercise.content_type |
59 | 56 | |
60 | 57 | # Check if exist a mimetype in database |
61 | 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 | 60 | # Create if not |
64 | 61 | except: |
65 | 62 | mtype = MimeType.objects.create( |
... | ... | @@ -67,11 +64,14 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
67 | 64 | icon = mime_type_to_material_icons[exercise_type] |
68 | 65 | ) |
69 | 66 | mtype.save() |
70 | - self.object.exercise_type = mtype | |
67 | + self.object.file_type = mtype | |
71 | 68 | except: |
72 | 69 | print('Exercise not uploaded') |
73 | 70 | |
74 | 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 | 75 | #CREATE LOG |
76 | 76 | self.log_context['topic_id'] = topic.id |
77 | 77 | self.log_context['topic_name'] = topic.name |
... | ... | @@ -85,12 +85,12 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
85 | 85 | |
86 | 86 | |
87 | 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 | 90 | users=self.object.topic.subject.students.all()) |
91 | 91 | |
92 | 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 | 94 | self.log_context['topic_id'] = self.object.topic.id |
95 | 95 | self.log_context['topic_name'] = self.object.topic.name |
96 | 96 | self.log_context['topic_slug'] = self.object.topic.slug |
... | ... | @@ -137,7 +137,7 @@ def render_exercise(request, id): |
137 | 137 | |
138 | 138 | log_context = {} |
139 | 139 | log_context['exercise_id'] = exercise.id |
140 | - log_context['exercise_name'] = exercise.name | |
140 | + log_context['exercise_name'] = exercise.name_exercise | |
141 | 141 | log_context['topic_id'] = exercise.topic.id |
142 | 142 | log_context['topic_name'] = exercise.topic.name |
143 | 143 | log_context['topic_slug'] = exercise.topic.slug | ... | ... |
files/migrations/0001_initial.py
1 | 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 | 3 | from __future__ import unicode_literals |
4 | 4 | |
5 | 5 | from django.db import migrations, models |
... | ... | @@ -12,8 +12,8 @@ class Migration(migrations.Migration): |
12 | 12 | initial = True |
13 | 13 | |
14 | 14 | dependencies = [ |
15 | - ('core', '0001_initial'), | |
16 | 15 | ('courses', '0001_initial'), |
16 | + ('core', '0001_initial'), | |
17 | 17 | ] |
18 | 18 | |
19 | 19 | operations = [ |
... | ... | @@ -27,8 +27,8 @@ class Migration(migrations.Migration): |
27 | 27 | ], |
28 | 28 | options={ |
29 | 29 | 'verbose_name_plural': 'Files', |
30 | - 'ordering': ('-id',), | |
31 | 30 | 'verbose_name': 'File', |
31 | + 'ordering': ('-id',), | |
32 | 32 | }, |
33 | 33 | bases=('courses.material',), |
34 | 34 | ), | ... | ... |
files/migrations/0002_topicfile_professor.py
forum/migrations/0001_initial.py
forum/migrations/0002_auto_20161116_1057.py
... | ... | @@ -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 | - ] |
... | ... | @@ -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 | 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 | 3 | from __future__ import unicode_literals |
4 | 4 | |
5 | 5 | from django.db import migrations, models |
... | ... | @@ -19,8 +19,8 @@ class Migration(migrations.Migration): |
19 | 19 | name='Link', |
20 | 20 | fields=[ |
21 | 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 | 24 | ('image', models.ImageField(blank=True, upload_to='links/')), |
25 | 25 | ], |
26 | 26 | options={ | ... | ... |
links/migrations/0002_auto_20161116_1338.py
... | ... | @@ -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 | -# -*- 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 | -# -*- 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 | 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 | 3 | from __future__ import unicode_literals |
4 | 4 | |
5 | 5 | from django.db import migrations, models |
... | ... | @@ -24,8 +24,8 @@ class Migration(migrations.Migration): |
24 | 24 | ], |
25 | 25 | options={ |
26 | 26 | 'verbose_name_plural': 'Answers', |
27 | - 'ordering': ('order',), | |
28 | 27 | 'verbose_name': 'Answer', |
28 | + 'ordering': ('order',), | |
29 | 29 | }, |
30 | 30 | ), |
31 | 31 | migrations.CreateModel( | ... | ... |
poll/migrations/0002_auto_20161116_1057.py
... | ... | @@ -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 | - ] |
... | ... | @@ -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 "" |
8 | 8 | msgstr "" |
9 | 9 | "Project-Id-Version: PACKAGE VERSION\n" |
10 | 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 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
13 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
14 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | @@ -18,19 +18,19 @@ msgstr "" |
18 | 18 | "Content-Transfer-Encoding: 8bit\n" |
19 | 19 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" |
20 | 20 | |
21 | -#: users/forms.py:60 | |
21 | +#: .\forms.py:60 | |
22 | 22 | msgid "Please enter a valid CPF" |
23 | 23 | msgstr "Por favor, insira um CPF válido" |
24 | 24 | |
25 | -#: users/forms.py:67 | |
25 | +#: .\forms.py:66 | |
26 | 26 | msgid "Please enter a valid date" |
27 | 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 | 30 | msgid "Login" |
31 | 31 | msgstr "Login" |
32 | 32 | |
33 | -#: users/models.py:14 | |
33 | +#: .\models.py:14 | |
34 | 34 | msgid "" |
35 | 35 | "Type a valid username. This fields should only contain letters, numbers and " |
36 | 36 | "the characteres: @/./+/-/_ ." |
... | ... | @@ -38,361 +38,359 @@ msgstr "" |
38 | 38 | "Digite um nome de usuário válido. Esse campo deve conter apenas letras, " |
39 | 39 | "números e os caracteres: @/./+/-/_ ." |
40 | 40 | |
41 | -#: users/models.py:17 | |
41 | +#: .\models.py:17 | |
42 | 42 | msgid "" |
43 | 43 | "A short name that will be used to identify you in the platform and to access " |
44 | 44 | "it" |
45 | 45 | msgstr "" |
46 | 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 | 49 | msgid "Mail" |
50 | 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 | 54 | msgid "Name" |
54 | 55 | msgstr "Nome" |
55 | 56 | |
56 | -#: users/models.py:20 | |
57 | +#: .\models.py:20 | |
57 | 58 | msgid "City" |
58 | 59 | msgstr "Cidade" |
59 | 60 | |
60 | -#: users/models.py:21 | |
61 | +#: .\models.py:21 | |
61 | 62 | msgid "State" |
62 | 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 | 66 | msgid "Gender" |
66 | 67 | msgstr "Gênero" |
67 | 68 | |
68 | -#: users/models.py:22 | |
69 | +#: .\models.py:22 | |
69 | 70 | msgid "Male" |
70 | 71 | msgstr "Masculino" |
71 | 72 | |
72 | -#: users/models.py:22 | |
73 | +#: .\models.py:22 | |
73 | 74 | msgid "Female" |
74 | 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 | 82 | msgid "Birth Date" |
82 | 83 | msgstr "Data de nascimento" |
83 | 84 | |
84 | -#: users/models.py:25 | |
85 | +#: .\models.py:25 | |
85 | 86 | msgid "Phone" |
86 | 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 | 91 | msgstr "CPF" |
91 | 92 | |
92 | -#: users/models.py:27 | |
93 | +#: .\models.py:27 | |
93 | 94 | msgid "Type" |
94 | 95 | msgstr "Tipo" |
95 | 96 | |
96 | -#: users/models.py:27 | |
97 | +#: .\models.py:27 | |
97 | 98 | msgid "Professor" |
98 | 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 | 102 | msgid "Student" |
102 | 103 | msgstr "Aluno" |
103 | 104 | |
104 | -#: users/models.py:28 | |
105 | +#: .\models.py:28 | |
105 | 106 | msgid "Titration" |
106 | 107 | msgstr "Título" |
107 | 108 | |
108 | -#: users/models.py:29 | |
109 | +#: .\models.py:29 | |
109 | 110 | msgid "Year of titration" |
110 | 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 | 118 | msgid "Curriculum" |
118 | 119 | msgstr "Currículo" |
119 | 120 | |
120 | -#: users/models.py:32 | |
121 | +#: .\models.py:32 | |
121 | 122 | msgid "Create Date" |
122 | 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 | 128 | msgstr "Administrador" |
127 | 129 | |
128 | -#: users/models.py:34 | |
130 | +#: .\models.py:34 | |
129 | 131 | msgid "Active" |
130 | 132 | msgstr "Ativo" |
131 | 133 | |
132 | -#: users/models.py:42 | |
134 | +#: .\models.py:42 | |
133 | 135 | msgid "User" |
134 | 136 | msgstr "Usuário" |
135 | 137 | |
136 | -#: users/models.py:43 | |
138 | +#: .\models.py:43 | |
137 | 139 | msgid "Users" |
138 | 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 | 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 | 148 | msgid "Search..." |
159 | 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 | 152 | msgid "Profile" |
167 | 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 | 156 | msgid "Email" |
171 | 157 | msgstr "Email" |
172 | 158 | |
173 | -#: users/templates/list_users.html:70 | |
159 | +#: .\templates\list_users.html:61 | |
174 | 160 | msgid "Contact" |
175 | 161 | msgstr "Contato" |
176 | 162 | |
177 | -#: users/templates/list_users.html:72 | |
163 | +#: .\templates\list_users.html:63 | |
178 | 164 | msgid "Edit" |
179 | 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 | 168 | msgid "Delete" |
183 | 169 | msgstr "Apagar" |
184 | 170 | |
185 | -#: users/templates/list_users.html:84 | |
171 | +#: .\templates\list_users.html:75 | |
186 | 172 | msgid "Confirm delete" |
187 | 173 | msgstr "Confirmar" |
188 | 174 | |
189 | -#: users/templates/list_users.html:87 | |
175 | +#: .\templates\list_users.html:78 | |
190 | 176 | msgid "Are you sure you want to delete the user" |
191 | 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 | 182 | msgid "Cancel" |
200 | 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 | 186 | msgid "No users found" |
204 | 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 | 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 | 194 | #, fuzzy |
214 | 195 | #| msgid "Password" |
215 | 196 | msgid "New Password" |
216 | 197 | msgstr "Senha" |
217 | 198 | |
218 | -#: users/templates/users/change_password.html:39 | |
199 | +#: .\templates\users\change_password.html:39 | |
219 | 200 | msgid "Confirmation" |
220 | 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 | 205 | msgid "Save" |
227 | 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 | 209 | msgid "Choose your photo..." |
233 | 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 | 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 | 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 | 226 | #, fuzzy |
289 | 227 | #| msgid "State" |
290 | 228 | msgid "Status" |
291 | 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 | 240 | msgid "User role" |
295 | 241 | msgstr "Tipo de usuário" |
296 | 242 | |
297 | -#: users/templates/users/profile.html:79 | |
243 | +#: .\templates\users\profile.html:82 | |
298 | 244 | msgid "Teacher" |
299 | 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 | 251 | msgstr "Não possui CPF" |
308 | 252 | |
309 | -#: users/templates/users/profile.html:96 | |
253 | +#: .\templates\users\profile.html:99 | |
310 | 254 | msgid "Phone Number" |
311 | 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 | 261 | msgstr "Não possui telefone" |
316 | 262 | |
317 | -#: users/templates/users/profile.html:113 | |
263 | +#: .\templates\users\profile.html:116 | |
318 | 264 | msgid "State and City" |
319 | 265 | msgstr "Estado e cidade" |
320 | 266 | |
321 | -#: users/templates/users/profile.html:117 | |
267 | +#: .\templates\users\profile.html:120 | |
322 | 268 | msgid "Title" |
323 | 269 | msgstr "Título" |
324 | 270 | |
325 | -#: users/templates/users/profile.html:121 | |
271 | +#: .\templates\users\profile.html:124 | |
326 | 272 | msgid "Year" |
327 | 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 | 276 | msgid "Didn't inform institution" |
335 | 277 | msgstr "Não informou a instituição" |
336 | 278 | |
337 | -#: users/templates/users/profile.html:139 | |
279 | +#: .\templates\users\profile.html:142 | |
338 | 280 | msgid "Didn't upload any curriculum" |
339 | 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 | 284 | msgid "Are you sure you want delete this account?" |
343 | 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 | 294 | msgid "Remove" |
352 | 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 | 302 | msgid "Mail:" |
364 | 303 | msgstr "E-mail" |
365 | 304 | |
366 | -#: users/templates/users/view.html:46 | |
305 | +#: .\templates\users\view.html:26 | |
367 | 306 | msgid "Phone:" |
368 | 307 | msgstr "Telefone" |
369 | 308 | |
370 | -#: users/templates/users/view.html:49 | |
309 | +#: .\templates\users\view.html:29 | |
371 | 310 | msgid "Cpf:" |
372 | 311 | msgstr "CPF" |
373 | 312 | |
374 | -#: users/templates/users/view.html:52 | |
313 | +#: .\templates\users\view.html:32 | |
375 | 314 | msgid "Birth date:" |
376 | 315 | msgstr "Data de nascimento:" |
377 | 316 | |
378 | -#: users/views.py:55 | |
317 | +#: .\views.py:70 | |
379 | 318 | msgid "User created successfully!" |
380 | 319 | msgstr "Usuário criado com sucesso!" |
381 | 320 | |
382 | -#: users/views.py:84 | |
321 | +#: .\views.py:99 | |
383 | 322 | msgid "User edited successfully!" |
384 | 323 | msgstr "Usuário editado com sucesso!" |
385 | 324 | |
386 | -#: users/views.py:101 | |
325 | +#: .\views.py:116 .\views.py:122 | |
387 | 326 | #, fuzzy |
388 | 327 | #| msgid "User edited successfully!" |
389 | 328 | msgid "User deleted Successfully!" |
390 | 329 | msgstr "Usuário editado com sucesso!" |
391 | 330 | |
392 | -#: users/views.py:126 | |
331 | +#: .\views.py:152 | |
393 | 332 | msgid "Profile edited successfully!" |
394 | 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 | 394 | #~ msgid "New User" |
397 | 395 | #~ msgstr "Novo usuário" |
398 | 396 | ... | ... |
users/migrations/0001_initial.py
users/models.py
... | ... | @@ -30,7 +30,7 @@ class User(AbstractBaseUser, PermissionsMixin): |
30 | 30 | institution = models.CharField(_('Institution'), max_length = 50, blank=True, null=True) |
31 | 31 | curriculum = models.FileField(verbose_name = _('Curriculum'), upload_to='users/curriculum/', null=True, blank=True) |
32 | 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 | 34 | is_active = models.BooleanField(_('Active'), default = True) |
35 | 35 | |
36 | 36 | USERNAME_FIELD = 'username' | ... | ... |
users/templates/list_users.html
users/templates/users/create.html
... | ... | @@ -38,8 +38,8 @@ |
38 | 38 | {% else %} |
39 | 39 | <label for="{{ field.auto_id }}">{{ field.label }}</label> |
40 | 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 | 43 | {% elif field.auto_id == 'id_image' %} |
44 | 44 | {% if field.field.required %} |
45 | 45 | <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label> |
... | ... | @@ -71,10 +71,10 @@ |
71 | 71 | </button> |
72 | 72 | </span> |
73 | 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 | 75 | <div class="checkbox"> |
76 | 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 | 78 | </label> |
79 | 79 | </div> |
80 | 80 | {% elif field.auto_id == 'id_cpf' %} |
... | ... | @@ -123,10 +123,10 @@ |
123 | 123 | {% endif %} |
124 | 124 | </div> |
125 | 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 | 127 | <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-success" onclick="validarCpfSemAlert(id_cpf, CPF, idElementoMensagemErro)'" /> |
128 | 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 | 130 | <a href="{% url 'users:manage' %}" class="btn btn-raised btn-danger" >{% trans 'Cancel' %}</a> |
131 | 131 | </div> |
132 | 132 | </form> |
... | ... | @@ -136,4 +136,11 @@ |
136 | 136 | </br> |
137 | 137 | </br> |
138 | 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 | 146 | {% endblock %} | ... | ... |
users/templates/users/index.html
users/views.py
... | ... | @@ -39,7 +39,7 @@ class UsersListView(HasRoleMixin, LoginRequiredMixin, generic.ListView): |
39 | 39 | search = self.request.GET.get('search', None) |
40 | 40 | |
41 | 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 | 43 | else: |
44 | 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 | 67 | |
68 | 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 | 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 | 78 | class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView): |
75 | 79 | |
... | ... | @@ -96,7 +100,7 @@ class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView): |
96 | 100 | |
97 | 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 | 105 | return super(Update, self).form_valid(form) |
102 | 106 | |
... | ... | @@ -243,4 +247,3 @@ class UserViewSet(viewsets.ModelViewSet): |
243 | 247 | queryset = User.objects.all() |
244 | 248 | serializer_class = UserSerializer |
245 | 249 | permissions_classes = (IsAuthenticatedOrReadOnly,) |
246 | - | ... | ... |