Commit 4eb261b5eceaaef2c9e6ff9c264bad94021fb23d

Authored by Matheus Lins
1 parent e753a300

create, update and delete exercise (views, urls, templates)

Showing 43 changed files with 900 additions and 317 deletions   Show diff stats
amadeus/settings.py
... ... @@ -58,6 +58,7 @@ INSTALLED_APPS = [
58 58 'poll',
59 59 'links',
60 60 'files',
  61 + 'exercise',
61 62  
62 63 ]
63 64  
... ...
app/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5 5 from django.db import migrations, models
... ...
core/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5 5 import autoslug.fields
6   -from django.conf import settings
7 6 import django.contrib.postgres.fields.jsonb
8 7 from django.db import migrations, models
9 8 import django.db.models.deletion
... ... @@ -14,7 +13,6 @@ class Migration(migrations.Migration):
14 13 initial = True
15 14  
16 15 dependencies = [
17   - migrations.swappable_dependency(settings.AUTH_USER_MODEL),
18 16 ]
19 17  
20 18 operations = [
... ... @@ -35,7 +33,6 @@ class Migration(migrations.Migration):
35 33 name='Action_Resource',
36 34 fields=[
37 35 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
38   - ('action', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action', verbose_name='Action_Applied')),
39 36 ],
40 37 options={
41 38 'verbose_name': 'Action_Resource',
... ... @@ -49,8 +46,6 @@ class Migration(migrations.Migration):
49 46 ('component', models.TextField(verbose_name='Component (Module / App)')),
50 47 ('context', django.contrib.postgres.fields.jsonb.JSONField(blank=True, verbose_name='Context')),
51 48 ('datetime', models.DateTimeField(auto_now_add=True, verbose_name='Date and Time of action')),
52   - ('action_resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action_Resource', verbose_name='Action_Resource')),
53   - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Actor')),
54 49 ],
55 50 options={
56 51 'verbose_name': 'Log',
... ... @@ -77,8 +72,6 @@ class Migration(migrations.Migration):
77 72 ('read', models.BooleanField(default=False, verbose_name='Read')),
78 73 ('datetime', models.DateTimeField(auto_now_add=True, verbose_name='Date and Time of action')),
79 74 ('action_resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Action_Resource', verbose_name='Action_Resource')),
80   - ('actor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notification_Performer', to=settings.AUTH_USER_MODEL, verbose_name='Perfomer')),
81   - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notification_Actor', to=settings.AUTH_USER_MODEL, verbose_name='User')),
82 75 ],
83 76 options={
84 77 'verbose_name': 'Notification',
... ... @@ -99,9 +92,4 @@ class Migration(migrations.Migration):
99 92 'verbose_name_plural': 'Resources',
100 93 },
101 94 ),
102   - migrations.AddField(
103   - model_name='action_resource',
104   - name='resource',
105   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Resource', verbose_name='Resource'),
106   - ),
107 95 ]
... ...
core/migrations/0002_auto_20161114_0144.py 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  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='Perfomer'),
  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 + ]
... ...
courses/admin.py
1 1 from django.contrib import admin
2 2  
3   -from .models import CourseCategory, Course, Subject, Topic, Activity, Material, CategorySubject, Exercise
  3 +from .models import CourseCategory, Course, Subject, Topic, Activity, Material, CategorySubject
4 4  
5 5 class CategoryAdmin(admin.ModelAdmin):
6 6 list_display = ['name', 'slug']
... ... @@ -30,15 +30,10 @@ class MaterialAdmin(admin.ModelAdmin):
30 30 list_display = ['name', 'slug']
31 31 search_fields = ['name', 'slug']
32 32  
33   -class ExerciseAdmin(admin.ModelAdmin):
34   - list_display = ['name']
35   - search_fields = ['name']
36   -
37 33 admin.site.register(CourseCategory, CategoryAdmin)
38 34 admin.site.register(Course, CourseAdmin)
39 35 admin.site.register(Subject, SubjectAdmin)
40 36 admin.site.register(Topic, TopicAdmin)
41 37 admin.site.register(Activity, ActivityAdmin)
42 38 admin.site.register(Material, MaterialAdmin)
43   -admin.site.register(Exercise, ExerciseAdmin)
44 39 admin.site.register(CategorySubject, CategorySubjectAdmin)
... ...
courses/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5 5 import autoslug.fields
6   -from django.conf import settings
7 6 from django.db import migrations, models
8 7 import django.db.models.deletion
9 8 import s3direct.fields
... ... @@ -15,7 +14,6 @@ class Migration(migrations.Migration):
15 14  
16 15 dependencies = [
17 16 ('core', '0001_initial'),
18   - migrations.swappable_dependency(settings.AUTH_USER_MODEL),
19 17 ]
20 18  
21 19 operations = [
... ... @@ -25,7 +23,6 @@ class Migration(migrations.Migration):
25 23 ('resource_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Resource')),
26 24 ('limit_date', models.DateField(verbose_name='Deliver Date')),
27 25 ('all_students', models.BooleanField(default=False, verbose_name='All Students')),
28   - ('students', models.ManyToManyField(related_name='activities', to=settings.AUTH_USER_MODEL, verbose_name='Students')),
29 26 ],
30 27 bases=('core.resource',),
31 28 ),
... ... @@ -35,7 +32,6 @@ class Migration(migrations.Migration):
35 32 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
36 33 ('pdf', s3direct.fields.S3DirectField()),
37 34 ('name', models.CharField(max_length=100)),
38   - ('diet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='files', to='courses.Activity')),
39 35 ],
40 36 options={
41 37 'verbose_name': 'Activity File',
... ... @@ -72,9 +68,9 @@ class Migration(migrations.Migration):
72 68 ('public', models.BooleanField(default=False, verbose_name='Public')),
73 69 ],
74 70 options={
  71 + 'ordering': ('create_date', 'name'),
75 72 'verbose_name': 'Course',
76 73 'verbose_name_plural': 'Courses',
77   - 'ordering': ('create_date', 'name'),
78 74 },
79 75 ),
80 76 migrations.CreateModel(
... ... @@ -112,7 +108,6 @@ class Migration(migrations.Migration):
112 108 fields=[
113 109 ('resource_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Resource')),
114 110 ('all_students', models.BooleanField(default=False, verbose_name='All Students')),
115   - ('students', models.ManyToManyField(related_name='materials', to=settings.AUTH_USER_MODEL, verbose_name='Students')),
116 111 ],
117 112 bases=('core.resource',),
118 113 ),
... ... @@ -128,15 +123,11 @@ class Migration(migrations.Migration):
128 123 ('end_date', models.DateField(verbose_name='End of Subject Date')),
129 124 ('create_date', models.DateTimeField(auto_now_add=True, verbose_name='Creation Date')),
130 125 ('update_date', models.DateTimeField(auto_now=True, verbose_name='Date of last update')),
131   - ('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subject_category', to='courses.CategorySubject', verbose_name='Category')),
132   - ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subjects', to='courses.Course', verbose_name='Course')),
133   - ('professors', models.ManyToManyField(related_name='professors_subjects', to=settings.AUTH_USER_MODEL, verbose_name='Professors')),
134   - ('students', models.ManyToManyField(blank=True, related_name='subject_student', to=settings.AUTH_USER_MODEL, verbose_name='Students')),
135 126 ],
136 127 options={
  128 + 'ordering': ('create_date', 'name'),
137 129 'verbose_name': 'Subject',
138 130 'verbose_name_plural': 'Subjects',
139   - 'ordering': ('create_date', 'name'),
140 131 },
141 132 ),
142 133 migrations.CreateModel(
... ... @@ -146,7 +137,6 @@ class Migration(migrations.Migration):
146 137 ('name', models.CharField(max_length=100, verbose_name='Name')),
147 138 ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True, verbose_name='Slug')),
148 139 ('description', models.TextField(blank=True, verbose_name='Description')),
149   - ('subjects', models.ManyToManyField(to='courses.Subject')),
150 140 ],
151 141 options={
152 142 'verbose_name': 'subject category',
... ... @@ -163,53 +153,11 @@ class Migration(migrations.Migration):
163 153 ('create_date', models.DateTimeField(auto_now_add=True, verbose_name='Creation Date')),
164 154 ('update_date', models.DateTimeField(auto_now=True, verbose_name='Date of last update')),
165 155 ('visible', models.BooleanField(default=False, verbose_name='Visible')),
166   - ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Owner')),
167   - ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Subject', verbose_name='Subject')),
168 156 ],
169 157 options={
  158 + 'ordering': ('create_date', 'name'),
170 159 'verbose_name': 'Topic',
171 160 'verbose_name_plural': 'Topics',
172   - 'ordering': ('create_date', 'name'),
173 161 },
174 162 ),
175   - migrations.AddField(
176   - model_name='material',
177   - name='topic',
178   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materials', to='courses.Topic', verbose_name='Topic'),
179   - ),
180   - migrations.AddField(
181   - model_name='linkmaterial',
182   - name='material',
183   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_link', to='courses.Material', verbose_name='Material'),
184   - ),
185   - migrations.AddField(
186   - model_name='filematerial',
187   - name='material',
188   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_file', to='courses.Material', verbose_name='Material'),
189   - ),
190   - migrations.AddField(
191   - model_name='course',
192   - name='category',
193   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_category', to='courses.CourseCategory', verbose_name='Category'),
194   - ),
195   - migrations.AddField(
196   - model_name='course',
197   - name='coordenator',
198   - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='course_coordenator', to=settings.AUTH_USER_MODEL, verbose_name='Coordenator'),
199   - ),
200   - migrations.AddField(
201   - model_name='course',
202   - name='professors',
203   - field=models.ManyToManyField(related_name='courses_professors', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),
204   - ),
205   - migrations.AddField(
206   - model_name='course',
207   - name='students',
208   - field=models.ManyToManyField(blank=True, related_name='courses_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
209   - ),
210   - migrations.AddField(
211   - model_name='activity',
212   - name='topic',
213   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='courses.Topic', verbose_name='Topic'),
214   - ),
215 163 ]
... ...
courses/migrations/0002_auto_20161114_0144.py 0 → 100644
... ... @@ -0,0 +1,110 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  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='topic',
  22 + name='owner',
  23 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Owner'),
  24 + ),
  25 + migrations.AddField(
  26 + model_name='topic',
  27 + name='subject',
  28 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Subject', verbose_name='Subject'),
  29 + ),
  30 + migrations.AddField(
  31 + model_name='subjectcategory',
  32 + name='subjects',
  33 + field=models.ManyToManyField(to='courses.Subject'),
  34 + ),
  35 + migrations.AddField(
  36 + model_name='subject',
  37 + name='category',
  38 + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subject_category', to='courses.CategorySubject', verbose_name='Category'),
  39 + ),
  40 + migrations.AddField(
  41 + model_name='subject',
  42 + name='course',
  43 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subjects', to='courses.Course', verbose_name='Course'),
  44 + ),
  45 + migrations.AddField(
  46 + model_name='subject',
  47 + name='professors',
  48 + field=models.ManyToManyField(related_name='professors_subjects', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),
  49 + ),
  50 + migrations.AddField(
  51 + model_name='subject',
  52 + name='students',
  53 + field=models.ManyToManyField(blank=True, related_name='subject_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  54 + ),
  55 + migrations.AddField(
  56 + model_name='material',
  57 + name='students',
  58 + field=models.ManyToManyField(related_name='materials', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  59 + ),
  60 + migrations.AddField(
  61 + model_name='material',
  62 + name='topic',
  63 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materials', to='courses.Topic', verbose_name='Topic'),
  64 + ),
  65 + migrations.AddField(
  66 + model_name='linkmaterial',
  67 + name='material',
  68 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_link', to='courses.Material', verbose_name='Material'),
  69 + ),
  70 + migrations.AddField(
  71 + model_name='filematerial',
  72 + name='material',
  73 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_file', to='courses.Material', verbose_name='Material'),
  74 + ),
  75 + migrations.AddField(
  76 + model_name='course',
  77 + name='category',
  78 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_category', to='courses.CourseCategory', verbose_name='Category'),
  79 + ),
  80 + migrations.AddField(
  81 + model_name='course',
  82 + name='coordenator',
  83 + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='course_coordenator', to=settings.AUTH_USER_MODEL, verbose_name='Coordenator'),
  84 + ),
  85 + migrations.AddField(
  86 + model_name='course',
  87 + name='professors',
  88 + field=models.ManyToManyField(related_name='courses_professors', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),
  89 + ),
  90 + migrations.AddField(
  91 + model_name='course',
  92 + name='students',
  93 + field=models.ManyToManyField(blank=True, related_name='courses_student', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  94 + ),
  95 + migrations.AddField(
  96 + model_name='activityfile',
  97 + name='diet',
  98 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='files', to='courses.Activity'),
  99 + ),
  100 + migrations.AddField(
  101 + model_name='activity',
  102 + name='students',
  103 + field=models.ManyToManyField(related_name='activities', to=settings.AUTH_USER_MODEL, verbose_name='Students'),
  104 + ),
  105 + migrations.AddField(
  106 + model_name='activity',
  107 + name='topic',
  108 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='courses.Topic', verbose_name='Topic'),
  109 + ),
  110 + ]
... ...
courses/migrations/0002_exercise.py
... ... @@ -1,25 +0,0 @@
1   -# -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 19:30
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   - ('courses', '0001_initial'),
13   - ]
14   -
15   - operations = [
16   - migrations.CreateModel(
17   - name='Exercise',
18   - fields=[
19   - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20   - ('file', models.FileField(upload_to='uploads/%Y/%m/%d')),
21   - ('name', models.CharField(max_length=100)),
22   - ('exercise', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_exercise', to='courses.Material', verbose_name='Material')),
23   - ],
24   - ),
25   - ]
courses/models.py
... ... @@ -157,14 +157,6 @@ class LinkMaterial(models.Model):
157 157 name = models.CharField(max_length=100)
158 158 description = models.TextField()
159 159 url = models.URLField('Link', max_length=300)
160   -"""
161   -It represents the Exercises inside topic.
162   -"""
163   -
164   -class Exercise(models.Model):
165   - exercise = models.ForeignKey(Material, verbose_name = _('Material'), related_name='material_exercise')
166   - file = models.FileField(upload_to='uploads/%Y/%m/%d')
167   - name = models.CharField(max_length=100)
168 160  
169 161 """
170 162 It is a category for each subject.
... ...
courses/templates/exercise/create_exercise.html
... ... @@ -1,74 +0,0 @@
1   -{% load widget_tweaks i18n %}
2   -<!--MODAL CREATE LINK-->
3   -<div class="modal fade" id="createLinksModal" tabindex="-1" role="dialog" aria-labelledby="createLink">
4   - <div class="modal-dialog" role="document">
5   - <div class="modal-content">
6   - <div class="modal-header">
7   - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
8   - <h4 class="modal-title" id="createLink">{% trans 'Create a New Exercise' %}</h4>
9   - </div>
10   - <div class="modal-body">
11   - <!-- Card -->
12   - <form method="post" action="" id="form-link" enctype="multipart/form-data">
13   - {% csrf_token %}
14   - {% for field in form %}
15   - <div class ="form-group">
16   - {% if field.field.required %}
17   - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>
18   - {% endif %}
19   - {% render_field field class='form-control input-sm' %}
20   - {% if field.errors %}
21   - <div class="alert alert-danger alert-dismissible clearfix" role="alert">
22   - <button type="button" class="close" data-dismiss="alert" aria-label="Close">
23   - <span aria-hidden="true">&times;</span>
24   - </button>
25   - <ul>
26   - {% for error in field.errors %}
27   - <li>{{ error }}</li>
28   - {% endfor %}
29   - </ul>
30   - </div>
31   - {% endif %}
32   - </div>
33   - {% endfor %}
34   - <div class="form-group">
35   - <button type="button" class="btn btn-raised btn-default " data-dismiss="modal">{% trans "Cancel" %}</button>
36   - <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
37   - </div>
38   - <!-- .end Card -->
39   - </div>
40   - </div>
41   - </div>
42   -</div>
43   -<!-- EndModal -->
44   -{% block script_link %}
45   - {# // <script src="{% static 'js/links.js' %}"></script> #}
46   - <script type="text/javascript">
47   - $("#form-link").submit(function(event) {
48   - $("#createLinksModal").modal("hide");
49   - var data = new FormData($('#form-link').get(0));
50   - $.ajax({
51   - url: "{% url 'course:links:create_link' topic.slug %}",
52   - type: $("#form-link").attr('method'),
53   - data: data,
54   - cache: false,
55   - processData: false,
56   - contentType: false,
57   - success: function(data) {
58   - $('#requisicoes_ajax').empty();
59   - $('#list-topic{{ topic.id }}-links').append(data);
60   - $('#list-topic{{ topic.id }}-links-edit').append(data);
61   - alertify.alert('Link successfully created!')
62   - },
63   - error: function(data){
64   - $("div.modal-backdrop.fade.in").remove();
65   - $('#requisicoes_ajax').empty();
66   - $('#requisicoes_ajax').append(data.responseText);
67   - $('#createLinksModal').modal('show');
68   - alertify.alert('Invalid link, insert a valid one!');
69   - }
70   - });
71   - event.preventDefault();
72   - });
73   - </script>
74   -{% endblock script_link %}
75 0 \ No newline at end of file
courses/templates/exercise/exercise_edit.html
... ... @@ -1,7 +0,0 @@
1   -{% load static i18n list_topic_foruns permission_tags %}
2   -<div id="exercise-topic{{ exercise.id }}-exercises-edit">
3   - {% for exercise in exercises %}
4   - <li class="icon_edit_remove" id = "exercise_edit_icon_{{ exercise.slug }}"> <a href="javascript:modal.get('{% url 'course:update_exercise' exercise.slug %}', '#exercisesModalEdit', '#requisicoes_ajax')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:delete_exercise' exercise.slug %}', '#exerciseDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li>
5   - <li id = "exercise_edit_{{ exercise.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:view_exercise' exercise.slug %}', '#viewExerciseModal','#requisicoes_ajax')">{{exercise.name}}</a></li>
6   - {% endfor %}
7   -</div>
courses/templates/exercise/exercise_list.html
... ... @@ -1,6 +0,0 @@
1   -{% load static i18n list_topic_foruns permission_tags %}
2   -<div id="list-topic{{ topic.id }}-exercises">
3   -{% for exercise in exercises %}
4   - <li id = "exercise_{{ exercise.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:view_exercise' exercise.slug %}', '#viewExerciseModal','#requisicoes_ajax')">{{exercise.name}}</a></li>
5   -{% endfor %}
6   -</div>
courses/templates/subject/form_view_student.html
... ... @@ -67,6 +67,15 @@
67 67 <div class="resource_inline">
68 68 <h4>{% trans 'Exercises' %}</h4>
69 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>
70 79 <div class="presentation_{{exercise.slug}}">
71 80 {# exercício do tópico no modo de visualização #}
72 81 <ul>
... ...
courses/templatetags/list_topic_exercises.py
... ... @@ -1,25 +0,0 @@
1   -from django import template
2   -from courses.models import Exercise
3   -
4   -register = template.Library()
5   -
6   -
7   -@register.inclusion_tag('exercise/exercise_list.html')
8   -def list_topic_exercise(request):
9   - context = {
10   - 'request': request,
11   - }
12   - context['exercises'] = Exercise.objects.all()
13   -
14   - return context
15   -
16   -
17   -@register.inclusion_tag('exercise/exercise_edit.html')
18   -def list_topic_exercise_edit(request, exercise):
19   - context = {
20   - 'request': request,
21   - }
22   - context['exercises'] = Exercise.objects.all()
23   - context['exercise'] = exercise
24   -
25   - return context
courses/urls.py
... ... @@ -2,38 +2,39 @@ from django.conf.urls import url, include
2 2  
3 3 from . import views
4 4 urlpatterns = [
5   - url(r'^$', views.IndexView.as_view(), name='manage'),
6   - url(r'^all-courses/$', views.AllCoursesView.as_view(), name='all_courses'),
7   - url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
8   - url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'),
9   - url(r'^replicate_subject/(?P<slug>[\w_-]+)/$', views.ReplicateSubjectView.as_view(), name='replicate_subject'),
10   - url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'),
11   - url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'),
12   - url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_course, name='subscribe'),
13   - url(r'^category/(?P<slug>[\w_-]+)/$', views.FilteredView.as_view(), name='filter'),
14   - url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'),
15   - url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"),
16   - url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'),
17   - url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'),
18   - url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'),
19   - url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'),
20   - url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'),
21   - url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'),
22   - url(r'^subjects/subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_subject, name='subscribe_subject'),
23   - url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'),
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='update_topic'),
26   - url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'),
27   - url(r'^subjects/categories$',views.IndexSubjectCategoryView.as_view(), name='subject_category_index'),
28   - url(r'^forum/', include('forum.urls', namespace = 'forum')),
29   - url(r'^poll/', include('poll.urls', namespace = 'poll')),
30   - url(r'^exam/', include('exam.urls', namespace = 'exam')),
31   - url(r'^files/', include('files.urls', namespace = 'file')),
32   - url(r'^upload-material/$', views.UploadMaterialView.as_view(), name='upload_material'),
33   - url(r'^subjects/file-material-view/(?P<slug>[\w_-]+)/$', views.FileMaterialView.as_view(), name='file_material_view'),
34   - url(r'^links/',include('links.urls',namespace = 'links')),
35   - url(r'^(?P<slug>[\w_-]+)/', include([
36   - url(r'^$', views.CourseView.as_view(), name='view'),
37   - url(r'^(?P<category>[\w_-]+)/$', views.CourseView.as_view(), name='view_filter')
38   - ])),
  5 + url(r'^$', views.IndexView.as_view(), name='manage'),
  6 + url(r'^all-courses/$', views.AllCoursesView.as_view(), name='all_courses'),
  7 + url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
  8 + url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'),
  9 + url(r'^replicate_subject/(?P<slug>[\w_-]+)/$', views.ReplicateSubjectView.as_view(), name='replicate_subject'),
  10 + url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'),
  11 + url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'),
  12 + url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_course, name='subscribe'),
  13 + url(r'^category/(?P<slug>[\w_-]+)/$', views.FilteredView.as_view(), name='filter'),
  14 + url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'),
  15 + url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"),
  16 + url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'),
  17 + url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'),
  18 + url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'),
  19 + url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'),
  20 + url(r'^subjects/update/(?P<slug>[\w_-]+)/$', views.UpdateSubjectView.as_view(), name='update_subject'),
  21 + url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'),
  22 + url(r'^subjects/subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_subject, name='subscribe_subject'),
  23 + url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'),
  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='update_topic'),
  26 + url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'),
  27 + url(r'^subjects/categories$',views.IndexSubjectCategoryView.as_view(), name='subject_category_index'),
  28 + url(r'^forum/', include('forum.urls', namespace = 'forum')),
  29 + url(r'^poll/', include('poll.urls', namespace = 'poll')),
  30 + url(r'^exam/', include('exam.urls', namespace = 'exam')),
  31 + url(r'^files/', include('files.urls', namespace = 'file')),
  32 + url(r'^upload-material/$', views.UploadMaterialView.as_view(), name='upload_material'),
  33 + url(r'^subjects/file-material-view/(?P<slug>[\w_-]+)/$', views.FileMaterialView.as_view(), name='file_material_view'),
  34 + url(r'^links/',include('links.urls',namespace = 'links')),
  35 + url(r'^exercise/', include('exercise.urls', namespace='exercise')),
  36 + url(r'^(?P<slug>[\w_-]+)/', include([
  37 + url(r'^$', views.CourseView.as_view(), name='view'),
  38 + url(r'^(?P<category>[\w_-]+)/$', views.CourseView.as_view(), name='view_filter')
  39 + ])),
39 40 ]
... ...
courses/views.py
1   -from django.shortcuts import get_object_or_404
2   -from django.views import generic
  1 +from .forms import CourseForm, UpdateCourseForm, CategoryCourseForm, SubjectForm,TopicForm,ActivityForm
  2 +from .models import Course, Subject, CourseCategory, Topic, SubjectCategory, Activity, CategorySubject
  3 +from core.decorators import log_decorator
  4 +from core.mixins import LogMixin, NotificationMixin
  5 +from core.models import Log
  6 +from courses.models import Material
  7 +from datetime import date, datetime
3 8 from django.contrib import messages
4 9 from django.contrib.auth.decorators import login_required
5   -from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
6 10 from django.contrib.auth.mixins import LoginRequiredMixin
7   -from rolepermissions.mixins import HasRoleMixin
  11 +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
8 12 from django.core.urlresolvers import reverse_lazy
9   -from django.utils.translation import ugettext_lazy as _
10   -from rolepermissions.verifications import has_role
11 13 from django.db.models import Q
12   -import operator
13   -from functools import reduce
14   -from rolepermissions.verifications import has_object_permission
15 14 from django.http import JsonResponse
16   -from .forms import CourseForm, UpdateCourseForm, CategoryCourseForm, SubjectForm,TopicForm,ActivityForm
17   -from .models import Course, Subject, CourseCategory,Topic, Exercise, SubjectCategory,Activity, CategorySubject
18   -from core.decorators import log_decorator
19   -from core.mixins import LogMixin, NotificationMixin
20   -from core.models import Log
21   -from users.models import User
  15 +from django.shortcuts import get_object_or_404
  16 +from django.urls import reverse
  17 +from django.utils.translation import ugettext_lazy as _
  18 +from django.views import generic
  19 +from exercise.models import Exercise
22 20 from files.forms import FileForm
23 21 from files.models import TopicFile
24   -from courses.models import Material
25   -from django.urls import reverse
26   -
27   -from datetime import date, datetime
  22 +from functools import reduce
  23 +from rolepermissions.mixins import HasRoleMixin
  24 +from rolepermissions.verifications import has_object_permission
  25 +from rolepermissions.verifications import has_role
  26 +from users.models import User
  27 +import operator
28 28 import time
29 29  
30 30 #API IMPORTS
... ... @@ -566,7 +566,7 @@ class SubjectsView(LoginRequiredMixin, LogMixin, generic.ListView):
566 566 context['course'] = subject.course
567 567 context['subject'] = subject
568 568 context['topics'] = Topic.objects.filter(subject = subject)
569   - context['exercise'] = Exercise.objects.filter(exercise__topic__subject=subject)
  569 + context['exercise'] = Exercise.objects.filter(topic__subject=subject)
570 570 if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'):
571 571 context['files'] = TopicFile.objects.filter(professor__name = self.request.user.name)
572 572 else:
... ...
exam/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5   -from django.conf import settings
6 5 from django.db import migrations, models
7 6 import django.db.models.deletion
8 7  
... ... @@ -13,7 +12,6 @@ class Migration(migrations.Migration):
13 12  
14 13 dependencies = [
15 14 ('courses', '0001_initial'),
16   - migrations.swappable_dependency(settings.AUTH_USER_MODEL),
17 15 ]
18 16  
19 17 operations = [
... ... @@ -25,9 +23,9 @@ class Migration(migrations.Migration):
25 23 ('order', models.PositiveSmallIntegerField(verbose_name='Order')),
26 24 ],
27 25 options={
  26 + 'ordering': ('order',),
28 27 'verbose_name': 'Answer',
29 28 'verbose_name_plural': 'Answers',
30   - 'ordering': ('order',),
31 29 },
32 30 ),
33 31 migrations.CreateModel(
... ... @@ -61,14 +59,4 @@ class Migration(migrations.Migration):
61 59 name='exam',
62 60 field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_exam', to='exam.Exam', verbose_name='Exam'),
63 61 ),
64   - migrations.AddField(
65   - model_name='answersstudent',
66   - name='student',
67   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student', to=settings.AUTH_USER_MODEL, verbose_name='Student'),
68   - ),
69   - migrations.AddField(
70   - model_name='answer',
71   - name='exam',
72   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='exam.Exam', verbose_name='Answers'),
73   - ),
74 62 ]
... ...
exam/migrations/0002_auto_20161114_0144.py 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  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/__init__.py 0 → 100644
exercise/admin.py 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +from django.contrib import admin
  2 +from .models import Exercise
  3 +
  4 +class ExerciseAdmin(admin.ModelAdmin):
  5 + list_display = ['name']
  6 + search_fields = ['name']
  7 +
  8 +admin.site.register(Exercise, ExerciseAdmin)
... ...
exercise/apps.py 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +from django.apps import AppConfig
  2 +
  3 +
  4 +class ExerciseConfig(AppConfig):
  5 + name = 'exercise'
... ...
exercise/forms.py 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +from .models import Exercise
  2 +from django import forms
  3 +from django.core.exceptions import ValidationError, FieldError
  4 +from django.utils.translation import ugettext_lazy as _
  5 +import requests
  6 +
  7 +
  8 +class ExerciseForm(forms.ModelForm):
  9 +
  10 + class Meta:
  11 + model = Exercise
  12 + fields = ['name', 'file']
  13 +
  14 +
  15 +class UpdateExerciseForm(forms.ModelForm):
  16 +
  17 + class Meta:
  18 + model = Exercise
  19 + fields = ['name', 'file']
... ...
exercise/migrations/0001_initial.py 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +import django.db.models.deletion
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + initial = True
  12 +
  13 + dependencies = [
  14 + ('courses', '0001_initial'),
  15 + ]
  16 +
  17 + operations = [
  18 + migrations.CreateModel(
  19 + name='Exercise',
  20 + fields=[
  21 + ('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)),
  24 + ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='courses.Topic', verbose_name='Topic')),
  25 + ],
  26 + ),
  27 + ]
... ...
exercise/migrations/__init__.py 0 → 100644
exercise/models.py 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +from django.db import models
  2 +from courses.models import Topic
  3 +from django.utils.translation import ugettext_lazy as _
  4 +
  5 +"""
  6 + Function to return the path where the file should be saved
  7 +"""
  8 +
  9 +
  10 +def file_path(instance, filename):
  11 + return '/'.join([instance.topic.subject.course.slug, instance.topic.subject.slug, instance.topic.slug, filename])
  12 +
  13 +
  14 +"""
  15 +It represents the Exercises inside topic.
  16 +"""
  17 +
  18 +
  19 +class Exercise(models.Model):
  20 + topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='exercises')
  21 + file = models.FileField(upload_to='uploads/%Y/%m/%d')
  22 + name = models.CharField(max_length=100)
... ...
exercise/static/js/exercise.js 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +function get_modal_link(url, id,div_content){
  2 + $.get(url, function (data) {
  3 + $(div_content).detach();
  4 + $(div_content).append(data);
  5 + $(id).modal('show');
  6 + });
  7 +}
... ...
exercise/templates/exercise/create_exercise.html 0 → 100644
... ... @@ -0,0 +1,82 @@
  1 +{% load widget_tweaks i18n static %}
  2 +<!--MODAL CREATE EXERCISE-->
  3 +<div class="modal fade" id="createExercisesModal" tabindex="-1" role="dialog" aria-labelledby="createExercise">
  4 + <div class="modal-dialog" role="document">
  5 + <div class="modal-content">
  6 + <div class="modal-header">
  7 + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
  8 + <h4 class="modal-title" id="createExercise">{% trans 'Create a New Exercise' %}</h4>
  9 + </div>
  10 + <div class="modal-body">
  11 + <!-- Card -->
  12 + <form method="post" action="" id="form-exercise" enctype="multipart/form-data">
  13 + {% csrf_token %}
  14 + {% if messages %}
  15 + {% for message in messages %}
  16 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  17 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  18 + <span aria-hidden="true">&times;</span>
  19 + </button>
  20 + <p>{{ message }}</p>
  21 + </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' %}
  30 + {% if field.errors %}
  31 + <div class="alert alert-danger alert-dismissible clearfix" role="alert">
  32 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  33 + <span aria-hidden="true">&times;</span>
  34 + </button>
  35 + <ul>
  36 + {% for error in field.errors %}
  37 + <li>{{ error }}</li>
  38 + {% endfor %}
  39 + </ul>
  40 + </div>
  41 + {% endif %}
  42 + </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>
  52 +</div>
  53 +<!-- EndModal -->
  54 +<script src="{% static 'js/exercises.js' %}"></script>
  55 +<script type="text/javascript">
  56 + $("#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 + }
  79 + });
  80 + event.preventDefault();
  81 + });
  82 +</script>
... ...
exercise/templates/exercise/delete_exercise.html 0 → 100644
... ... @@ -0,0 +1,66 @@
  1 +{% load static widget_tweaks i18n %}
  2 +
  3 +<!-- MODAL DELETE LINK -->
  4 +<exercise rel="stylesheet" type="text/css" href="{% static 'css/exercise.css' %}">
  5 +
  6 +<div class="erro-update">
  7 + <div class="modal fade" id="exerciseDeleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteExerciseLabel" style="z-index: 10">
  8 + <div class="modal-dialog" role="document">
  9 + <div class="modal-content">
  10 + <div class="modal-header">
  11 + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
  12 + <h4 class="modal-title" id="deleteExerciseLabel">{% trans 'Delete Exercise' %}</h4>
  13 + </div>
  14 + <div class="modal-body">
  15 + <!-- Card -->
  16 + <form class="form-horizontal" method="post" id="form-delete-exercise" enctype="multipart/form-data">
  17 + {% csrf_token %}
  18 + <fieldset>
  19 + <div class="col-md-12">
  20 + {% trans "Are you sure to delete the exercise " %} <strong>"{{ exercise.name }}"</strong> </a> of {{ exercise.topic.name }}?
  21 + </div>
  22 + <div class="form-group">
  23 + <div class="col-md-12">
  24 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  25 + <button class="btn btn-raised btn-primary" type="submit">{% trans 'Delete' %}</button>
  26 + </div>
  27 + </div>
  28 + </fieldset>
  29 + </form>
  30 + <!-- .end Card -->
  31 + </div>
  32 + </div>
  33 + </div>
  34 + </div>
  35 +</div>
  36 + <script src="{% static 'js/exercise.js' %}"></script>
  37 + <script type="text/javascript">
  38 + $("#form-delete-exercise").submit(function(event) {
  39 + var data = new FormData($('#form-delete-exercise').get(0));
  40 + $('#exerciseDeleteModal').modal('hide');
  41 + $.ajax({
  42 + url: "{% url 'course:exercises:delete_exercise' exercise.slug %}",
  43 + type: $("#form-delete-exercise").attr('method'),
  44 + data: data,
  45 + cache: false,
  46 + processData: false,
  47 + contentType: false,
  48 + success: function(data) {
  49 + $('#requisicoes_ajax').empty();
  50 + $('#exercise_{{ exercise.slug }}').remove();
  51 + $('#exercise_edit_icon_{{ exercise.slug }}').remove();
  52 + $('#exercise_edit_{{ exercise.slug }}').remove();
  53 + alertify.alert('Exercise successfully deleted!')
  54 + },
  55 + error: function(data){
  56 + $("div.modal-backdrop.fade.in").remove();
  57 + $('#requisicoes_ajax').empty();
  58 + $('#requisicoes_ajax').append(data.responseText);
  59 + $('#exerciseDeleteModal').modal('show');
  60 + alertify.alert('Error when trying to delete.');
  61 + }
  62 + });
  63 + event.preventDefault();
  64 + });
  65 + </script>
  66 +<!-- EndModal -->
... ...
exercise/templates/exercise/exercise_edit.html 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +{% load static i18n list_topic_foruns permission_tags %}
  2 +<div id="exercise-topic{{ exercise.id }}-exercises-edit">
  3 + {% for exercise in exercises %}
  4 + <li class="icon_edit_remove" id = "exercise_edit_icon_{{ exercise.slug }}"> <a href="javascript:modal.get('', '#exercisesModalEdit', '#requisicoes_ajax')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('', '#exerciseDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li>
  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>
  6 + {% endfor %}
  7 +</div>
... ...
exercise/templates/exercise/exercise_list.html 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +{% load static i18n list_topic_foruns permission_tags %}
  2 +<div id="list-topic{{ topic.id }}-exercises">
  3 +{% for exercise in exercises %}
  4 + <li id="exercise_{{ exercise.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="{{exercise.file.url}}">{{exercise.name}}</a></li>
  5 +{% endfor %}
  6 +</div>
... ...
exercise/templatetags/__init__.py 0 → 100644
exercise/templatetags/list_topic_exercises.py 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +from django import template
  2 +from exercise.models import Exercise
  3 +
  4 +register = template.Library()
  5 +
  6 +
  7 +@register.inclusion_tag('exercise/exercise_list.html')
  8 +def list_topic_exercise(request):
  9 + context = {
  10 + 'request': request,
  11 + }
  12 + context['exercises'] = Exercise.objects.all()
  13 +
  14 + return context
  15 +
  16 +
  17 +@register.inclusion_tag('exercise/exercise_edit.html')
  18 +def list_topic_exercise_edit(request, exercise):
  19 + context = {
  20 + 'request': request,
  21 + }
  22 + context['exercises'] = Exercise.objects.all()
  23 + context['exercise'] = exercise
  24 +
  25 + return context
... ...
exercise/tests.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
... ...
exercise/urls.py 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +from django.conf.urls import url
  2 +from . import views
  3 +
  4 +urlpatterns = [
  5 + url(r'^create_exercise/(?P<slug>[\w_-]+)/$', views.CreateExercise.as_view(), name='create_exercise'),
  6 + url(r'^delete_exercise/(?P<slug>[\w_-]+)/$', views.DeleteExercise.as_view(), name='delete_exercise'),
  7 + url(r'^update_exercise/(?P<slug>[\w_-]+)/$', views.UpdateExercise.as_view(), name='update_exercise'),
  8 + url(r'^render-exercise/(?P<id>[0-9]+)/$', views.render_exercise, name='render_exercise'),
  9 +]
... ...
exercise/views.py 0 → 100644
... ... @@ -0,0 +1,253 @@
  1 +from .forms import ExerciseForm, UpdateExerciseForm
  2 +from .models import Exercise
  3 +from files.utils import mime_type_to_material_icons
  4 +from core.decorators import log_decorator
  5 +from core.mixins import LogMixin, NotificationMixin
  6 +from core.models import Log, MimeType
  7 +from courses.models import Topic
  8 +from datetime import datetime
  9 +from django.conf import settings
  10 +from django.contrib import messages
  11 +from django.contrib.auth.mixins import LoginRequiredMixin
  12 +from django.core.urlresolvers import reverse_lazy
  13 +from django.shortcuts import render, get_object_or_404, redirect
  14 +from django.urls import reverse
  15 +from django.views import generic
  16 +from rolepermissions.mixins import HasRoleMixin
  17 +from rolepermissions.verifications import has_role
  18 +
  19 +
  20 +class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView):
  21 + log_component = 'exercise'
  22 + log_resource = 'exercise'
  23 + log_action = 'create'
  24 + log_component = {}
  25 +
  26 + allowed_roles = ['student']
  27 + login_url = reverse_lazy("core:home")
  28 + redirect_field_name = 'next'
  29 + model = Exercise
  30 + template_name = 'exercise/create_exercise.html'
  31 + form_class = ExerciseForm
  32 + success_url = reverse_lazy('course:exercise:render_exercise')
  33 +
  34 + log_component = "subject"
  35 + log_resource = "exercise"
  36 + log_action = "create"
  37 + log_context = {}
  38 + context_object_name = 'form'
  39 +
  40 + def form_invalid(self, form, **kwargs):
  41 + context = super(CreateExercise, self).form_invalid(form)
  42 + context.status_code = 400
  43 +
  44 + return context
  45 +
  46 + def form_valid(self, form):
  47 + self.object = form.save(commit = False)
  48 + topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  49 + self.object.topic = topic
  50 +
  51 + self.object.name = str(self.object)
  52 +
  53 +
  54 + # Set MimeType
  55 + exercise = self.request.FILES['exercise_url']
  56 + try:
  57 + if exercise:
  58 + exercise_type = exercise.content_type
  59 +
  60 + # Check if exist a mimetype in database
  61 + try:
  62 + self.object.exercise_type = MimeType.objects.get(typ = exercise_type)
  63 + # Create if not
  64 + except:
  65 + mtype = MimeType.objects.create(
  66 + typ = exercise_type,
  67 + icon = mime_type_to_material_icons[exercise_type]
  68 + )
  69 + mtype.save()
  70 + self.object.exercise_type = mtype
  71 + except:
  72 + print('Exercise not uploaded')
  73 +
  74 + self.object.save()
  75 + #CREATE LOG
  76 + self.log_context['topic_id'] = topic.id
  77 + self.log_context['topic_name'] = topic.name
  78 + self.log_context['topic_slug'] = topic.slug
  79 + self.log_context['subject_id'] = topic.subject.id
  80 + self.log_context['subject_name'] = topic.subject.name
  81 + self.log_context['subject_slug'] = topic.subject.slug
  82 +
  83 + super(CreateExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  84 +
  85 +
  86 +
  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]),
  90 + users=self.object.topic.subject.students.all())
  91 +
  92 + self.log_context['exercise_id'] = self.object.id
  93 + self.log_context['exercise_name'] = self.object.name
  94 + self.log_context['topic_id'] = self.object.topic.id
  95 + self.log_context['topic_name'] = self.object.topic.name
  96 + self.log_context['topic_slug'] = self.object.topic.slug
  97 + self.log_context['subject_id'] = self.object.topic.subject.id
  98 + self.log_context['subject_name'] = self.object.topic.subject.name
  99 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  100 + self.log_context['course_id'] = self.object.topic.subject.course.id
  101 + self.log_context['course_name'] = self.object.topic.subject.course.name
  102 + self.log_context['course_slug'] = self.object.topic.subject.course.slug
  103 + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id
  104 + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name
  105 +
  106 + super(CreateExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  107 +
  108 + return self.get_success_url()
  109 +
  110 + def get_context_data(self, **kwargs):
  111 + context = super(CreateExercise, self).get_context_data(**kwargs)
  112 + topic = get_object_or_404(Topic, slug=self.kwargs.get('slug'))
  113 + context['topic'] = topic
  114 + context['subject'] = topic.subject
  115 + context['subjects'] = topic.subject.course.subjects.all()
  116 + context['form'] = self.form_class
  117 +
  118 + try:
  119 + context['latest_exercise'] = Exercise.objects.latest('id')
  120 + except:
  121 + pass
  122 + return context
  123 +
  124 + def get_success_url(self):
  125 + self.success_url = redirect('course:exercise:render_exercise', id = self.object.id)
  126 +
  127 + return self.success_url
  128 +
  129 +
  130 +def render_exercise(request, id):
  131 + template_name = 'exercise/render_exercise.html'
  132 + exercise = get_object_or_404(Exercise, id = id)
  133 +
  134 + context = {
  135 + 'exercise': exercise
  136 + }
  137 +
  138 + log_context = {}
  139 + log_context['exercise_id'] = exercise.id
  140 + log_context['exercise_name'] = exercise.name
  141 + log_context['topic_id'] = exercise.topic.id
  142 + log_context['topic_name'] = exercise.topic.name
  143 + log_context['topic_slug'] = exercise.topic.slug
  144 + log_context['subject_id'] = exercise.topic.subject.id
  145 + log_context['subject_name'] = exercise.topic.subject.name
  146 + log_context['subject_slug'] = exercise.topic.subject.slug
  147 + log_context['course_id'] = exercise.topic.subject.course.id
  148 + log_context['course_name'] = exercise.topic.subject.course.name
  149 + log_context['course_slug'] = exercise.topic.subject.course.slug
  150 + log_context['course_category_id'] = exercise.topic.subject.course.category.id
  151 + log_context['course_category_name'] = exercise.topic.subject.course.category.name
  152 +
  153 + request.log_context = log_context
  154 +
  155 + return render(request, template_name, context)
  156 +
  157 +
  158 +class UpdateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView):
  159 + log_component = 'exercise'
  160 + log_resource = 'exercise'
  161 + log_action = 'update'
  162 + log_context = {}
  163 +
  164 + allowed_roles = ['student']
  165 + login_url = reverse_lazy("core:home")
  166 + redirect_field_name = 'next'
  167 + model = Exercise
  168 + template_name = 'exercise/update_exercise.html'
  169 + form_class = UpdateExerciseForm
  170 + context_object_name = 'exercise'
  171 + success_url = reverse_lazy('course:exercise:render_exercise')
  172 +
  173 + def form_invalid(self, form, **kwargs):
  174 + context = super(UpdateExercise, self).form_invalid(form)
  175 + context.status_code = 400
  176 +
  177 + return context
  178 +
  179 +
  180 + def form_valid(self, form):
  181 + self.object = form.save()
  182 +
  183 + self.log_context['exercise_id'] = self.object.id
  184 + self.log_context['exercise_name'] = self.object.name
  185 + self.log_context['topic_id'] = self.object.topic.id
  186 + self.log_context['topic_name'] = self.object.topic.name
  187 + self.log_context['topic_slug'] = self.object.topic.slug
  188 + self.log_context['subject_id'] = self.object.topic.subject.id
  189 + self.log_context['subject_name'] = self.object.topic.subject.name
  190 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  191 + self.log_context['course_id'] = self.object.topic.subject.course.id
  192 + self.log_context['course_name'] = self.object.topic.subject.course.name
  193 + self.log_context['course_slug'] = self.object.topic.subject.course.slug
  194 + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id
  195 + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name
  196 +
  197 + super(UpdateExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  198 +
  199 + return super(UpdateExercise, self).form_valid(form)
  200 +
  201 + def get_object(self, queryset=None):
  202 + return get_object_or_404(Exercise, slug = self.kwargs.get('slug'))
  203 +
  204 + def get_success_url(self):
  205 + self.success_url = reverse_lazy('course:exercise:render_exercise', args = (self.object.id, ))
  206 +
  207 + return self.success_url
  208 +
  209 +
  210 +class DeleteExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView):
  211 + log_component = 'exercise'
  212 + log_resource = 'exercise'
  213 + log_action = 'delete'
  214 + log_context = {}
  215 +
  216 + allowed_roles = ['student']
  217 + login_url = reverse_lazy("core:home")
  218 + redirect_field_name = 'next'
  219 + model = Exercise
  220 + template_name = 'exercise/delete_exercise.html'
  221 +
  222 + def dispatch(self, *args, **kwargs):
  223 + exercise = get_object_or_404(Exercise, slug = self.kwargs.get('slug'))
  224 + if(not (exercise.topic.owner == self.request.user) and not(has_role(self.request.user, 'system_admin')) ):
  225 + return self.handle_no_permission()
  226 + return super(DeleteExercise, self).dispatch(*args, **kwargs)
  227 +
  228 + def get_context_data(self, **kwargs):
  229 + context = super(DeleteExercise, self).get_context_data(**kwargs)
  230 + context['course'] = self.object.topic.subject.course
  231 + context['subject'] = self.object.topic.subject
  232 + context['exercise'] = self.object
  233 + context["topic"] = self.object.topic
  234 + return context
  235 +
  236 + def get_success_url(self):
  237 + self.log_context['exercise_id'] = self.object.id
  238 + self.log_context['exercise_name'] = self.object.name
  239 + self.log_context['topic_id'] = self.object.topic.id
  240 + self.log_context['topic_name'] = self.object.topic.name
  241 + self.log_context['topic_slug'] = self.object.topic.slug
  242 + self.log_context['subject_id'] = self.object.topic.subject.id
  243 + self.log_context['subject_name'] = self.object.topic.subject.name
  244 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  245 + self.log_context['course_id'] = self.object.topic.subject.course.id
  246 + self.log_context['course_name'] = self.object.topic.subject.course.name
  247 + self.log_context['course_slug'] = self.object.topic.subject.course.slug
  248 + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id
  249 + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name
  250 +
  251 + super(DeleteExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  252 +
  253 + return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug})
0 254 \ No newline at end of file
... ...
files/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5   -from django.conf import settings
6 5 from django.db import migrations, models
7 6 import django.db.models.deletion
8 7 import files.models
... ... @@ -15,7 +14,6 @@ class Migration(migrations.Migration):
15 14 dependencies = [
16 15 ('courses', '0001_initial'),
17 16 ('core', '0001_initial'),
18   - migrations.swappable_dependency(settings.AUTH_USER_MODEL),
19 17 ]
20 18  
21 19 operations = [
... ... @@ -26,12 +24,11 @@ class Migration(migrations.Migration):
26 24 ('description', models.TextField(blank=True, verbose_name='Description')),
27 25 ('file_url', models.FileField(upload_to=files.models.file_path, verbose_name='File')),
28 26 ('file_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='topic_files', to='core.MimeType', verbose_name='Type file')),
29   - ('professor', models.ManyToManyField(related_name='file_professors', to=settings.AUTH_USER_MODEL, verbose_name='Professors')),
30 27 ],
31 28 options={
  29 + 'ordering': ('-id',),
32 30 'verbose_name': 'File',
33 31 'verbose_name_plural': 'Files',
34   - 'ordering': ('-id',),
35 32 },
36 33 bases=('courses.material',),
37 34 ),
... ...
files/migrations/0002_topicfile_professor.py 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + initial = True
  12 +
  13 + dependencies = [
  14 + ('files', '0001_initial'),
  15 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  16 + ]
  17 +
  18 + operations = [
  19 + migrations.AddField(
  20 + model_name='topicfile',
  21 + name='professor',
  22 + field=models.ManyToManyField(related_name='file_professors', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),
  23 + ),
  24 + ]
... ...
forum/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5   -from django.conf import settings
6 5 from django.db import migrations, models
7 6 import django.db.models.deletion
8 7  
... ... @@ -13,7 +12,6 @@ class Migration(migrations.Migration):
13 12  
14 13 dependencies = [
15 14 ('courses', '0001_initial'),
16   - migrations.swappable_dependency(settings.AUTH_USER_MODEL),
17 15 ]
18 16  
19 17 operations = [
... ... @@ -38,8 +36,6 @@ class Migration(migrations.Migration):
38 36 ('message', models.TextField(verbose_name='Post message')),
39 37 ('modification_date', models.DateTimeField(auto_now=True, verbose_name='Modification Date')),
40 38 ('post_date', models.DateTimeField(auto_now_add=True, verbose_name='Post Date')),
41   - ('forum', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Forum', verbose_name='Forum')),
42   - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor')),
43 39 ],
44 40 options={
45 41 'verbose_name': 'Post',
... ... @@ -54,7 +50,6 @@ class Migration(migrations.Migration):
54 50 ('modification_date', models.DateTimeField(auto_now=True, verbose_name='Modification Date')),
55 51 ('answer_date', models.DateTimeField(auto_now_add=True, verbose_name='Answer Date')),
56 52 ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Post', verbose_name='Post')),
57   - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Autor')),
58 53 ],
59 54 options={
60 55 'verbose_name': 'Post Answer',
... ...
forum/migrations/0002_auto_20161114_0144.py 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  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 + ('forum', '0001_initial'),
  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-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5 5 from django.db import migrations, models
... ...
poll/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:47
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5   -from django.conf import settings
6 5 from django.db import migrations, models
7 6 import django.db.models.deletion
8 7  
... ... @@ -13,7 +12,6 @@ class Migration(migrations.Migration):
13 12  
14 13 dependencies = [
15 14 ('courses', '0001_initial'),
16   - migrations.swappable_dependency(settings.AUTH_USER_MODEL),
17 15 ]
18 16  
19 17 operations = [
... ... @@ -25,9 +23,9 @@ class Migration(migrations.Migration):
25 23 ('order', models.PositiveSmallIntegerField(verbose_name='Order')),
26 24 ],
27 25 options={
  26 + 'ordering': ('order',),
28 27 'verbose_name': 'Answer',
29 28 'verbose_name_plural': 'Answers',
30   - 'ordering': ('order',),
31 29 },
32 30 ),
33 31 migrations.CreateModel(
... ... @@ -59,14 +57,4 @@ class Migration(migrations.Migration):
59 57 name='poll',
60 58 field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundet', to='poll.Poll', verbose_name='Poll'),
61 59 ),
62   - migrations.AddField(
63   - model_name='answersstudent',
64   - name='student',
65   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundent', to=settings.AUTH_USER_MODEL, verbose_name='Student'),
66   - ),
67   - migrations.AddField(
68   - model_name='answer',
69   - name='poll',
70   - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='poll.Poll', verbose_name='Answers'),
71   - ),
72 60 ]
... ...
poll/migrations/0002_auto_20161114_0144.py 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
  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/migrations/0001_initial.py
1 1 # -*- coding: utf-8 -*-
2   -# Generated by Django 1.10 on 2016-11-13 17:42
  2 +# Generated by Django 1.10 on 2016-11-14 04:44
3 3 from __future__ import unicode_literals
4 4  
5 5 import django.contrib.auth.models
... ... @@ -46,8 +46,8 @@ class Migration(migrations.Migration):
46 46 ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
47 47 ],
48 48 options={
49   - 'verbose_name_plural': 'Users',
50 49 'verbose_name': 'User',
  50 + 'verbose_name_plural': 'Users',
51 51 },
52 52 managers=[
53 53 ('objects', django.contrib.auth.models.UserManager()),
... ...