Commit 1905b483b32fd81fbb8d7fc9e7979c621222142e
1 parent
cae4d31d
Exists in
master
and in
5 other branches
improviment the exercise's create model
Showing
10 changed files
with
116 additions
and
188 deletions
Show diff stats
courses/views.py
| ... | ... | @@ -16,7 +16,7 @@ from django.shortcuts import get_object_or_404 |
| 16 | 16 | from django.urls import reverse |
| 17 | 17 | from django.utils.translation import ugettext_lazy as _ |
| 18 | 18 | from django.views import generic |
| 19 | -from exercise.models import Exercise, File | |
| 19 | +from exercise.models import Exercise | |
| 20 | 20 | from files.forms import FileForm |
| 21 | 21 | from files.models import TopicFile |
| 22 | 22 | from functools import reduce | ... | ... |
exercise/admin.py
| 1 | 1 | from django.contrib import admin |
| 2 | -from .models import Exercise, File | |
| 2 | +from .models import Exercise | |
| 3 | 3 | |
| 4 | 4 | class ExerciseAdmin(admin.ModelAdmin): |
| 5 | 5 | list_display = ['name_exercise'] |
| 6 | 6 | search_fields = ['name_exercise'] |
| 7 | 7 | |
| 8 | -class FileAdmin(admin.ModelAdmin): | |
| 9 | - list_display = ['name_file'] | |
| 10 | - search_fields = ['name_file'] | |
| 11 | - | |
| 12 | 8 | admin.site.register(Exercise, ExerciseAdmin) |
| 13 | -admin.site.register(File, FileAdmin) | ... | ... |
exercise/forms.py
| ... | ... | @@ -10,7 +10,7 @@ class ExerciseForm(forms.ModelForm): |
| 10 | 10 | class Meta: |
| 11 | 11 | model = Exercise |
| 12 | 12 | fields = ['name_exercise', 'description', 'init_date', |
| 13 | - 'end_date', 'name_exercise'] | |
| 13 | + 'end_date', 'file'] | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | class UpdateExerciseForm(forms.ModelForm): |
| ... | ... | @@ -18,4 +18,4 @@ class UpdateExerciseForm(forms.ModelForm): |
| 18 | 18 | class Meta: |
| 19 | 19 | model = Exercise |
| 20 | 20 | fields = ['name_exercise', 'description', 'init_date', |
| 21 | - 'end_date', 'grade', 'name_exercise'] | |
| 21 | + 'end_date', 'grade', 'file'] | ... | ... |
exercise/migrations/0001_initial.py
| 1 | 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 | 3 | from __future__ import unicode_literals |
| 4 | 4 | |
| 5 | 5 | from decimal import Decimal |
| 6 | +from django.conf import settings | |
| 6 | 7 | from django.db import migrations, models |
| 7 | 8 | import django.db.models.deletion |
| 9 | +import exercise.models | |
| 8 | 10 | |
| 9 | 11 | |
| 10 | 12 | class Migration(migrations.Migration): |
| ... | ... | @@ -12,7 +14,9 @@ class Migration(migrations.Migration): |
| 12 | 14 | initial = True |
| 13 | 15 | |
| 14 | 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 | 22 | operations = [ |
| ... | ... | @@ -20,21 +24,16 @@ class Migration(migrations.Migration): |
| 20 | 24 | name='Exercise', |
| 21 | 25 | fields=[ |
| 22 | 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 | 29 | ('init_date', models.DateField(verbose_name='Begin of Subject Date')), |
| 25 | 30 | ('end_date', models.DateField(verbose_name='End of Subject Date')), |
| 26 | 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 | -# -*- 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 | -# -*- 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 | -# -*- 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 | 20 | |
| 21 | 21 | |
| 22 | 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 | 25 | init_date = models.DateField(_('Begin of Subject Date')) |
| 28 | 26 | end_date = models.DateField(_('End of Subject Date')) |
| 29 | 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 | 32 | file_type = models.ForeignKey(MimeType, verbose_name=_('Type file'), related_name='exercise_type') |
| 41 | 33 | |
| 42 | 34 | def __str__(self): |
| 43 | - return self.name_file | |
| 44 | 35 | \ No newline at end of file |
| 36 | + return self.name_exercise | |
| 45 | 37 | \ No newline at end of file | ... | ... |
exercise/templates/exercise/create_exercise.html
| ... | ... | @@ -9,74 +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 | 84 | <script type="text/javascript"> |
| 55 | 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 | 112 | </script> | ... | ... |
exercise/views.py
| ... | ... | @@ -48,19 +48,19 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
| 48 | 48 | topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) |
| 49 | 49 | self.object.topic = topic |
| 50 | 50 | self.object.name = str(self.object) |
| 51 | + self.object.exercise = self.object | |
| 51 | 52 | self.object.professors = topic.subject.professors |
| 52 | 53 | self.object.students = topic.subject.students |
| 53 | 54 | |
| 54 | 55 | # Set MimeType |
| 55 | 56 | exercise = self.request.FILES['exercise_url'] |
| 56 | - self.object.file_exercise.file = exercise | |
| 57 | 57 | try: |
| 58 | 58 | if exercise: |
| 59 | 59 | exercise_type = exercise.content_type |
| 60 | 60 | |
| 61 | 61 | # Check if exist a mimetype in database |
| 62 | 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 | 64 | # Create if not |
| 65 | 65 | except: |
| 66 | 66 | mtype = MimeType.objects.create( |
| ... | ... | @@ -68,7 +68,7 @@ class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMix |
| 68 | 68 | icon = mime_type_to_material_icons[exercise_type] |
| 69 | 69 | ) |
| 70 | 70 | mtype.save() |
| 71 | - self.object.file_exercise.file_type = mtype | |
| 71 | + self.object.file_type = mtype | |
| 72 | 72 | except: |
| 73 | 73 | print('Exercise not uploaded') |
| 74 | 74 | ... | ... |