Commit 1905b483b32fd81fbb8d7fc9e7979c621222142e

Authored by Matheus Lins
1 parent cae4d31d

improviment the exercise's create model

courses/views.py
@@ -16,7 +16,7 @@ from django.shortcuts import get_object_or_404 @@ -16,7 +16,7 @@ from django.shortcuts import get_object_or_404
16 from django.urls import reverse 16 from django.urls import reverse
17 from django.utils.translation import ugettext_lazy as _ 17 from django.utils.translation import ugettext_lazy as _
18 from django.views import generic 18 from django.views import generic
19 -from exercise.models import Exercise, File 19 +from exercise.models import Exercise
20 from files.forms import FileForm 20 from files.forms import FileForm
21 from files.models import TopicFile 21 from files.models import TopicFile
22 from functools import reduce 22 from functools import reduce
exercise/admin.py
1 from django.contrib import admin 1 from django.contrib import admin
2 -from .models import Exercise, File 2 +from .models import Exercise
3 3
4 class ExerciseAdmin(admin.ModelAdmin): 4 class ExerciseAdmin(admin.ModelAdmin):
5 list_display = ['name_exercise'] 5 list_display = ['name_exercise']
6 search_fields = ['name_exercise'] 6 search_fields = ['name_exercise']
7 7
8 -class FileAdmin(admin.ModelAdmin):  
9 - list_display = ['name_file']  
10 - search_fields = ['name_file']  
11 -  
12 admin.site.register(Exercise, ExerciseAdmin) 8 admin.site.register(Exercise, ExerciseAdmin)
13 -admin.site.register(File, FileAdmin)  
exercise/forms.py
@@ -10,7 +10,7 @@ class ExerciseForm(forms.ModelForm): @@ -10,7 +10,7 @@ class ExerciseForm(forms.ModelForm):
10 class Meta: 10 class Meta:
11 model = Exercise 11 model = Exercise
12 fields = ['name_exercise', 'description', 'init_date', 12 fields = ['name_exercise', 'description', 'init_date',
13 - 'end_date', 'name_exercise'] 13 + 'end_date', 'file']
14 14
15 15
16 class UpdateExerciseForm(forms.ModelForm): 16 class UpdateExerciseForm(forms.ModelForm):
@@ -18,4 +18,4 @@ class UpdateExerciseForm(forms.ModelForm): @@ -18,4 +18,4 @@ class UpdateExerciseForm(forms.ModelForm):
18 class Meta: 18 class Meta:
19 model = Exercise 19 model = Exercise
20 fields = ['name_exercise', 'description', 'init_date', 20 fields = ['name_exercise', 'description', 'init_date',
21 - 'end_date', 'grade', 'name_exercise'] 21 + 'end_date', 'grade', 'file']
exercise/migrations/0001_initial.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 -# Generated by Django 1.10 on 2016-11-17 05:17 2 +# Generated by Django 1.10 on 2016-11-17 08:09
3 from __future__ import unicode_literals 3 from __future__ import unicode_literals
4 4
5 from decimal import Decimal 5 from decimal import Decimal
  6 +from django.conf import settings
6 from django.db import migrations, models 7 from django.db import migrations, models
7 import django.db.models.deletion 8 import django.db.models.deletion
  9 +import exercise.models
8 10
9 11
10 class Migration(migrations.Migration): 12 class Migration(migrations.Migration):
@@ -12,7 +14,9 @@ class Migration(migrations.Migration): @@ -12,7 +14,9 @@ class Migration(migrations.Migration):
12 initial = True 14 initial = True
13 15
14 dependencies = [ 16 dependencies = [
15 - ('core', '0001_initial'), 17 + ('courses', '0002_auto_20161117_0217'),
  18 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  19 + ('core', '0002_auto_20161117_0217'),
16 ] 20 ]
17 21
18 operations = [ 22 operations = [
@@ -20,21 +24,16 @@ class Migration(migrations.Migration): @@ -20,21 +24,16 @@ class Migration(migrations.Migration):
20 name='Exercise', 24 name='Exercise',
21 fields=[ 25 fields=[
22 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 26 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23 - ('description', models.TextField(blank=True, verbose_name='Descrição')), 27 + ('name_exercise', models.CharField(max_length=100, verbose_name='Exercise Name')),
  28 + ('description', models.TextField(blank=True, verbose_name='Description')),
24 ('init_date', models.DateField(verbose_name='Begin of Subject Date')), 29 ('init_date', models.DateField(verbose_name='Begin of Subject Date')),
25 ('end_date', models.DateField(verbose_name='End of Subject Date')), 30 ('end_date', models.DateField(verbose_name='End of Subject Date')),
26 ('grade', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=20, null=True)), 31 ('grade', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=20, null=True)),
27 - ('name', models.CharField(max_length=100)),  
28 - ],  
29 - ),  
30 - migrations.CreateModel(  
31 - name='File',  
32 - fields=[  
33 - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),  
34 - ('name', models.CharField(max_length=100)),  
35 - ('file', models.FileField(upload_to='uploads/%Y/%m/%d')),  
36 - ('exercise', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='file', to='exercise.Exercise')),  
37 - ('file_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='file_files', to='core.MimeType', verbose_name='Type file')), 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')),
  36 + ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='courses.Topic', verbose_name='Topic')),
38 ], 37 ],
39 ), 38 ),
40 ] 39 ]
exercise/migrations/0002_auto_20161117_0217.py
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
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 - ('courses', '0002_auto_20161117_0217'),  
16 - ('exercise', '0001_initial'),  
17 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
18 - ]  
19 -  
20 - operations = [  
21 - migrations.AddField(  
22 - model_name='exercise',  
23 - name='professors',  
24 - field=models.ManyToManyField(blank=True, related_name='professors_exercise', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),  
25 - ),  
26 - migrations.AddField(  
27 - model_name='exercise',  
28 - name='students',  
29 - field=models.ManyToManyField(blank=True, related_name='subject_exercise', to=settings.AUTH_USER_MODEL, verbose_name='Students'),  
30 - ),  
31 - migrations.AddField(  
32 - model_name='exercise',  
33 - name='topic',  
34 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='courses.Topic', verbose_name='Topic'),  
35 - ),  
36 - ]  
exercise/migrations/0003_auto_20161117_0351.py
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-17 06:51  
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 - ('exercise', '0002_auto_20161117_0217'),  
12 - ]  
13 -  
14 - operations = [  
15 - migrations.AlterField(  
16 - model_name='file',  
17 - name='name',  
18 - field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Nome do arquivo'),  
19 - ),  
20 - ]  
exercise/migrations/0004_auto_20161117_0357.py
@@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-17 06:57  
3 -from __future__ import unicode_literals  
4 -  
5 -import datetime  
6 -from django.db import migrations, models  
7 -from django.utils.timezone import utc  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - dependencies = [  
13 - ('exercise', '0003_auto_20161117_0351'),  
14 - ]  
15 -  
16 - operations = [  
17 - migrations.RenameField(  
18 - model_name='file',  
19 - old_name='name',  
20 - new_name='name_file',  
21 - ),  
22 - migrations.RemoveField(  
23 - model_name='exercise',  
24 - name='name',  
25 - ),  
26 - migrations.AddField(  
27 - model_name='exercise',  
28 - name='name_exercise',  
29 - field=models.CharField(default=datetime.datetime(2016, 11, 17, 6, 57, 41, 28915, tzinfo=utc), max_length=100, verbose_name='Nome do Exercício'),  
30 - preserve_default=False,  
31 - ),  
32 - ]  
exercise/models.py
@@ -20,24 +20,16 @@ It represents the Exercises inside topic. @@ -20,24 +20,16 @@ It represents the Exercises inside topic.
20 20
21 21
22 class Exercise(models.Model): 22 class Exercise(models.Model):
23 - topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='exercises')  
24 - professors = models.ManyToManyField(User, verbose_name=_('Professors'), related_name='professors_exercise', blank=True)  
25 - students = models.ManyToManyField(User, verbose_name=_('Students'), related_name='subject_exercise', blank = True)  
26 - description = models.TextField(_('Descrição'), blank=True) 23 + name_exercise = models.CharField(_('Name'), max_length=100)
  24 + description = models.TextField(_('Description'), blank=True)
27 init_date = models.DateField(_('Begin of Subject Date')) 25 init_date = models.DateField(_('Begin of Subject Date'))
28 end_date = models.DateField(_('End of Subject Date')) 26 end_date = models.DateField(_('End of Subject Date'))
29 grade = models.DecimalField(max_digits=20, decimal_places=2, default=Decimal('0.00'), null=True) 27 grade = models.DecimalField(max_digits=20, decimal_places=2, default=Decimal('0.00'), null=True)
30 - name_exercise = models.CharField(_('Nome do Exercício'), max_length=100)  
31 -  
32 - def __str__(self):  
33 - return self.name_exercise  
34 -  
35 -  
36 -class File(models.Model):  
37 - name_file = models.CharField(_('Nome do arquivo'), max_length=100, blank=True, null=True)  
38 - file = models.FileField(upload_to='uploads/%Y/%m/%d')  
39 - exercise = models.ForeignKey(Exercise, related_name='file_exercise') 28 + topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='exercises')
  29 + professors = models.ManyToManyField(User, verbose_name=_('Professors'), related_name='professors_exercise', blank=True)
  30 + students = models.ManyToManyField(User, verbose_name=_('Students'), related_name='subject_exercise', blank = True)
  31 + file = models.FileField(upload_to=file_path)
40 file_type = models.ForeignKey(MimeType, verbose_name=_('Type file'), related_name='exercise_type') 32 file_type = models.ForeignKey(MimeType, verbose_name=_('Type file'), related_name='exercise_type')
41 33
42 def __str__(self): 34 def __str__(self):
43 - return self.name_file  
44 \ No newline at end of file 35 \ No newline at end of file
  36 + return self.name_exercise
45 \ No newline at end of file 37 \ No newline at end of file
exercise/templates/exercise/create_exercise.html
@@ -9,74 +9,104 @@ @@ -9,74 +9,104 @@
9 </div> 9 </div>
10 <div class="modal-body"> 10 <div class="modal-body">
11 <!-- Card --> 11 <!-- Card -->
12 - <form method="post" action="" id="form-exercise" enctype="multipart/form-data"> 12 + <form class="form-horizontal" method="post" id="form-exercise" enctype="multipart/form-data">
13 {% csrf_token %} 13 {% csrf_token %}
14 {% if messages %} 14 {% if messages %}
15 - {% for message in messages %}  
16 - <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">  
17 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
18 - <span aria-hidden="true">&times;</span> 15 + {% for message in messages %}
  16 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  17 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  18 + <span aria-hidden="true">&times;</span>
  19 + </button>
  20 + <p>{{ message }}</p>
  21 + </div>
  22 + {% endfor %}
  23 + {% endif %}
  24 + <fieldset>
  25 + {% for field in form %}
  26 + <div class="form-group is-empy{% if form.has_error %} has-error {% endif %} is-fileinput">
  27 + <div class="col-md-12">
  28 + {% if field.field.required %}
  29 + <label for="{{ field.auto_id }}" class="control-label">{{ field.label }}<span>*</span></label>
  30 + {% else %}
  31 + <label for="{{ field.auto_id }}" class=" control-label">{{ field.label }}</label>
  32 + {% endif %}
  33 + {% if field.auto_id == 'id_file' %}
  34 + {% render_field field class='form-control input-sm' %}
  35 + <div class="input-group">
  36 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">
  37 + <span class="input-group-btn input-group-sm">
  38 + <button type="button" class="btn btn-fab btn-fab-mini">
  39 + <i class="material-icons">attach_file</i>
19 </button> 40 </button>
20 - <p>{{ message }}</p> 41 + </span>
21 </div> 42 </div>
22 - {% endfor %}  
23 - {% endif %}  
24 - {% for field in form %}  
25 - <div class ="form-group">  
26 - {% if field.field.required %}  
27 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
28 - {% endif %}  
29 - {% render_field field class='form-control input-sm' %} 43 + {% else %}
  44 + {% render_field field class='form-control input-sm' %}
  45 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  46 + {% endif %}
  47 + </div>
  48 +
30 {% if field.errors %} 49 {% if field.errors %}
31 - <div class="alert alert-danger alert-dismissible clearfix" role="alert">  
32 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
33 - <span aria-hidden="true">&times;</span>  
34 - </button>  
35 - <ul>  
36 - {% for error in field.errors %}  
37 - <li>{{ error }}</li>  
38 - {% endfor %}  
39 - </ul>  
40 - </div> 50 + <div class="alert alert-danger alert-dismissible clearfix" role="alert">
  51 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  52 + <span aria-hidden="true">&times;</span>
  53 + </button>
  54 + <ul>
  55 + {% for error in field.errors %}
  56 + <li>{{ error }}</li>
  57 + {% endfor %}
  58 + </ul>
  59 + </div>
41 {% endif %} 60 {% endif %}
42 </div> 61 </div>
43 - {% endfor %}  
44 - <div class="form-group">  
45 - <button type="button" class="btn btn-raised btn-default " data-dismiss="modal">{% trans "Cancel" %}</button>  
46 - <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>  
47 - </div>  
48 - <!-- .end Card -->  
49 - </div>  
50 - </div>  
51 - </div> 62 + {% endfor %}
  63 +
  64 + <div class="form-group">
  65 + <div class="col-md-12 text-center">
  66 + <p><b>{% trans 'The file size shouldnt exceed 10MB' %}</b></p>
  67 + </div>
  68 + </div>
  69 +
  70 + <div class="form-group">
  71 + <div class="col-md-12">
  72 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  73 + <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
  74 + </div>
  75 + </div>
  76 + </fieldset>
  77 + </form>
  78 + <!-- .end Card -->
  79 + </div>
  80 + </div>
  81 + </div>
52 </div> 82 </div>
53 <!-- EndModal --> 83 <!-- EndModal -->
54 <script type="text/javascript"> 84 <script type="text/javascript">
55 $("#form-exercise").submit(function(event) { 85 $("#form-exercise").submit(function(event) {
56 - $("#createExercisesModal").modal("hide");  
57 - var data = new FormData($('#form-exercise').get(0));  
58 - $.ajax({  
59 - url: "{% url 'course:exercise:create_exercise' topic.slug %}",  
60 - type: $("#form-exercise").attr('method'),  
61 - data: data,  
62 - cache: false,  
63 - processData: false,  
64 - contentType: false,  
65 - success: function(data) {  
66 - $('#createExercisesModal').modal('hide');  
67 - $('#list-topic{{ topic.id }}-exercises').append(data);  
68 - $('#list-topic{{ topic.id }}-exercises-edit').append(data);  
69 - alertify.success('Exercise successfully created!')  
70 - },  
71 - error: function(data){  
72 - $('#requisicoes_ajax').empty();  
73 - $('#requisicoes_ajax').append(data.responseText);  
74 - $('#createExercisesModal').modal('show');  
75 - alertify.alert('Invalid exercise, insert a valid one!');  
76 - $('div.modal-backdrop.fade.in').remove();  
77 - setTimeout(function () { location.reload(1); }, 1000);  
78 - }  
79 - });  
80 - event.preventDefault();  
81 - }); 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 + });
82 </script> 112 </script>
exercise/views.py
@@ -48,19 +48,19 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -48,19 +48,19 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
48 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) 48 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
49 self.object.topic = topic 49 self.object.topic = topic
50 self.object.name = str(self.object) 50 self.object.name = str(self.object)
  51 + self.object.exercise = self.object
51 self.object.professors = topic.subject.professors 52 self.object.professors = topic.subject.professors
52 self.object.students = topic.subject.students 53 self.object.students = topic.subject.students
53 54
54 # Set MimeType 55 # Set MimeType
55 exercise = self.request.FILES['exercise_url'] 56 exercise = self.request.FILES['exercise_url']
56 - self.object.file_exercise.file = exercise  
57 try: 57 try:
58 if exercise: 58 if exercise:
59 exercise_type = exercise.content_type 59 exercise_type = exercise.content_type
60 60
61 # Check if exist a mimetype in database 61 # Check if exist a mimetype in database
62 try: 62 try:
63 - self.object.file_exercise.file_type = MimeType.objects.get(typ = exercise_type) 63 + self.object.file_type = MimeType.objects.get(typ = exercise_type)
64 # Create if not 64 # Create if not
65 except: 65 except:
66 mtype = MimeType.objects.create( 66 mtype = MimeType.objects.create(
@@ -68,7 +68,7 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix @@ -68,7 +68,7 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix
68 icon = mime_type_to_material_icons[exercise_type] 68 icon = mime_type_to_material_icons[exercise_type]
69 ) 69 )
70 mtype.save() 70 mtype.save()
71 - self.object.file_exercise.file_type = mtype 71 + self.object.file_type = mtype
72 except: 72 except:
73 print('Exercise not uploaded') 73 print('Exercise not uploaded')
74 74