From 38906abc4306ac9a0e52ed831ccef2e26f4f1138 Mon Sep 17 00:00:00 2001
From: janmax <mail-github@jmx.io>
Date: Thu, 23 Mar 2017 01:28:38 +0100
Subject: [PATCH] refactor and migration squash

---
 core/custom_annotations.py                    |  21 ++
 core/migrations/0001_initial.py               |  25 --
 .../0001_squashed_0034_auto_20170322_1304.py  | 292 ++++++++++++++++++
 core/migrations/0002_auto_20170303_1837.py    |  75 -----
 ...cription.py => 0002_auto_20170323_0026.py} |  11 +-
 core/migrations/0003_auto_20170303_2053.py    |  39 ---
 .../0004_submission_final_feedback.py         |  21 --
 core/migrations/0005_auto_20170304_1200.py    |  25 --
 core/migrations/0006_auto_20170304_1523.py    |  21 --
 core/migrations/0007_feedback_slug.py         |  20 --
 core/migrations/0008_auto_20170304_1612.py    |  20 --
 core/migrations/0009_auto_20170304_1614.py    |  20 --
 core/migrations/0010_auto_20170304_1741.py    |  21 --
 core/migrations/0011_auto_20170306_1327.py    |  34 --
 core/migrations/0012_auto_20170306_1450.py    |  20 --
 core/migrations/0013_auto_20170306_1452.py    |  19 --
 core/migrations/0014_auto_20170306_1504.py    |  25 --
 core/migrations/0015_auto_20170306_1525.py    |  41 ---
 core/migrations/0016_auto_20170306_1535.py    |  21 --
 core/migrations/0017_auto_20170306_1550.py    |  25 --
 core/migrations/0018_auto_20170306_1605.py    |  25 --
 core/migrations/0019_auto_20170307_1735.py    |  40 ---
 core/migrations/0020_auto_20170307_2031.py    |  20 --
 core/migrations/0021_auto_20170307_2122.py    |  25 --
 core/migrations/0022_auto_20170308_1439.py    |  25 --
 core/migrations/0023_auto_20170310_1422.py    |  26 --
 core/migrations/0024_auto_20170310_1502.py    |  24 --
 core/migrations/0025_auto_20170311_1637.py    |  31 --
 core/migrations/0026_submission_seen.py       |  20 --
 core/migrations/0028_auto_20170314_1726.py    |  30 --
 core/migrations/0029_feedback_empty.py        |  20 --
 core/migrations/0030_auto_20170315_1444.py    |  27 --
 core/migrations/0031_auto_20170315_1603.py    |  25 --
 core/migrations/0032_auto_20170315_1609.py    |  26 --
 core/migrations/0033_auto_20170321_2128.py    |  31 --
 core/migrations/0034_auto_20170322_1304.py    |  22 --
 core/models.py                                |   3 +-
 core/views.py                                 | 121 +-------
 core/viewset/__init__.py                      |   2 +
 core/viewset/feedback.py                      |  87 ++++++
 core/viewset/submission.py                    |  22 ++
 41 files changed, 436 insertions(+), 1012 deletions(-)
 create mode 100644 core/custom_annotations.py
 delete mode 100644 core/migrations/0001_initial.py
 create mode 100644 core/migrations/0001_squashed_0034_auto_20170322_1304.py
 delete mode 100644 core/migrations/0002_auto_20170303_1837.py
 rename core/migrations/{0027_submissiontype_description.py => 0002_auto_20170323_0026.py} (51%)
 delete mode 100644 core/migrations/0003_auto_20170303_2053.py
 delete mode 100644 core/migrations/0004_submission_final_feedback.py
 delete mode 100644 core/migrations/0005_auto_20170304_1200.py
 delete mode 100644 core/migrations/0006_auto_20170304_1523.py
 delete mode 100644 core/migrations/0007_feedback_slug.py
 delete mode 100644 core/migrations/0008_auto_20170304_1612.py
 delete mode 100644 core/migrations/0009_auto_20170304_1614.py
 delete mode 100644 core/migrations/0010_auto_20170304_1741.py
 delete mode 100644 core/migrations/0011_auto_20170306_1327.py
 delete mode 100644 core/migrations/0012_auto_20170306_1450.py
 delete mode 100644 core/migrations/0013_auto_20170306_1452.py
 delete mode 100644 core/migrations/0014_auto_20170306_1504.py
 delete mode 100644 core/migrations/0015_auto_20170306_1525.py
 delete mode 100644 core/migrations/0016_auto_20170306_1535.py
 delete mode 100644 core/migrations/0017_auto_20170306_1550.py
 delete mode 100644 core/migrations/0018_auto_20170306_1605.py
 delete mode 100644 core/migrations/0019_auto_20170307_1735.py
 delete mode 100644 core/migrations/0020_auto_20170307_2031.py
 delete mode 100644 core/migrations/0021_auto_20170307_2122.py
 delete mode 100644 core/migrations/0022_auto_20170308_1439.py
 delete mode 100644 core/migrations/0023_auto_20170310_1422.py
 delete mode 100644 core/migrations/0024_auto_20170310_1502.py
 delete mode 100644 core/migrations/0025_auto_20170311_1637.py
 delete mode 100644 core/migrations/0026_submission_seen.py
 delete mode 100644 core/migrations/0028_auto_20170314_1726.py
 delete mode 100644 core/migrations/0029_feedback_empty.py
 delete mode 100644 core/migrations/0030_auto_20170315_1444.py
 delete mode 100644 core/migrations/0031_auto_20170315_1603.py
 delete mode 100644 core/migrations/0032_auto_20170315_1609.py
 delete mode 100644 core/migrations/0033_auto_20170321_2128.py
 delete mode 100644 core/migrations/0034_auto_20170322_1304.py
 create mode 100644 core/viewset/__init__.py
 create mode 100644 core/viewset/feedback.py
 create mode 100644 core/viewset/submission.py

diff --git a/core/custom_annotations.py b/core/custom_annotations.py
new file mode 100644
index 00000000..857df0b6
--- /dev/null
+++ b/core/custom_annotations.py
@@ -0,0 +1,21 @@
+from django.contrib.auth.decorators import user_passes_test
+
+
+"""I collect custom decorators here that I use for the simple premission system
+
+Currently the following options are available
+    - group_required
+    - in_groups
+"""
+
+
+def in_groups(user, group_list):
+    return bool(user.groups.filter(name__in=group_list)) or user.is_superuser
+
+
+def group_required(*group_names):
+    """Requires user membership in at least one of the groups passed in."""
+    def _in_groups(u):
+        if u.is_authenticated():
+            return in_groups(u, group_names)
+    return user_passes_test(_in_groups)
diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py
deleted file mode 100644
index 84f7cc74..00000000
--- a/core/migrations/0001_initial.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-03 15:39
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    initial = True
-
-    dependencies = [
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='SubmissionType',
-            fields=[
-                ('type_id', models.CharField(max_length=20, primary_key=True, serialize=False)),
-                ('name', models.CharField(max_length=50)),
-                ('correct_solution', models.TextField()),
-                ('correction_guideline', models.TextField()),
-            ],
-        ),
-    ]
diff --git a/core/migrations/0001_squashed_0034_auto_20170322_1304.py b/core/migrations/0001_squashed_0034_auto_20170322_1304.py
new file mode 100644
index 00000000..791b608c
--- /dev/null
+++ b/core/migrations/0001_squashed_0034_auto_20170322_1304.py
@@ -0,0 +1,292 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-03-23 00:24
+from __future__ import unicode_literals
+
+import core.models
+from django.conf import settings
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    replaces = [('core', '0001_initial'), ('core', '0002_auto_20170303_1837'), ('core', '0003_auto_20170303_2053'), ('core', '0004_submission_final_feedback'), ('core', '0005_auto_20170304_1200'), ('core', '0006_auto_20170304_1523'), ('core', '0007_feedback_slug'), ('core', '0008_auto_20170304_1612'), ('core', '0009_auto_20170304_1614'), ('core', '0010_auto_20170304_1741'), ('core', '0011_auto_20170306_1327'), ('core', '0012_auto_20170306_1450'), ('core', '0013_auto_20170306_1452'), ('core', '0014_auto_20170306_1504'), ('core', '0015_auto_20170306_1525'), ('core', '0016_auto_20170306_1535'), ('core', '0017_auto_20170306_1550'), ('core', '0018_auto_20170306_1605'), ('core', '0019_auto_20170307_1735'), ('core', '0020_auto_20170307_2031'), ('core', '0021_auto_20170307_2122'), ('core', '0022_auto_20170308_1439'), ('core', '0023_auto_20170310_1422'), ('core', '0024_auto_20170310_1502'), ('core', '0025_auto_20170311_1637'), ('core', '0026_submission_seen'), ('core', '0027_submissiontype_description'), ('core', '0028_auto_20170314_1726'), ('core', '0029_feedback_empty'), ('core', '0030_auto_20170315_1444'), ('core', '0031_auto_20170315_1603'), ('core', '0032_auto_20170315_1609'), ('core', '0033_auto_20170321_2128'), ('core', '0034_auto_20170322_1304')]
+
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='SubmissionType',
+            fields=[
+                ('type_id', models.CharField(max_length=20, primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=50)),
+                ('correct_solution', models.TextField()),
+                ('correction_guideline', models.TextField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Feedback',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('score', models.PositiveIntegerField(default=0)),
+                ('text', models.TextField()),
+                ('of_reviewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviewd_submissions', to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'verbose_name': 'Feedback',
+                'verbose_name_plural': 'Feedbacks',
+            },
+        ),
+        migrations.CreateModel(
+            name='Student',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('matrikel_no', models.PositiveIntegerField(default=0, unique=True)),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Submission',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('pre_corrections', models.TextField()),
+                ('student', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='core.Student')),
+            ],
+            options={
+                'verbose_name': 'Submission',
+                'verbose_name_plural': 'Submissions',
+            },
+        ),
+        migrations.AlterModelOptions(
+            name='submissiontype',
+            options={'verbose_name': 'SubmissionType', 'verbose_name_plural': 'SubmissionTypes'},
+        ),
+        migrations.AddField(
+            model_name='submissiontype',
+            name='full_score',
+            field=models.PositiveIntegerField(default=0),
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='submission_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submissions', to='core.SubmissionType'),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='of_submission',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Submission'),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='of_tutor',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='corrected_submissions', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterModelOptions(
+            name='feedback',
+            options={'verbose_name': 'Feedback', 'verbose_name_plural': 'Feedback Set'},
+        ),
+        migrations.AlterModelOptions(
+            name='student',
+            options={'verbose_name': 'Student', 'verbose_name_plural': 'Student Set'},
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='submission_text',
+            field=models.TextField(),
+        ),
+        migrations.RemoveField(
+            model_name='feedback',
+            name='of_reviewer',
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='of_reviewer',
+            field=models.ManyToManyField(blank=True, related_name='reviewd_submissions', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='pre_corrections',
+            field=models.TextField(blank=True),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='slug',
+            field=models.SlugField(editable=False),
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='student',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Student'),
+        ),
+        migrations.CreateModel(
+            name='SubmissionStatus',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('status', models.CharField(choices=[('R', 'READY'), ('CP', 'CORRECTION_IN_PROGRESS'), ('FL', 'FEEDBACK_LIMIT_REACHED'), ('RE', 'REVIEWED')], default=('R', 'READY'), max_length=2)),
+                ('feedback_counter', models.PositiveIntegerField(default=0, editable=False)),
+                ('final_feedback', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Feedback')),
+                ('submission', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='core.Submission')),
+            ],
+        ),
+        migrations.AlterModelOptions(
+            name='submissionstatus',
+            options={'verbose_name': 'Submission Status', 'verbose_name_plural': 'SubmissionStatus Set'},
+        ),
+        migrations.RemoveField(
+            model_name='submissiontype',
+            name='type_id',
+        ),
+        migrations.AddField(
+            model_name='submissiontype',
+            name='id',
+            field=models.AutoField(auto_created=True, default=123, primary_key=True, serialize=False, verbose_name='ID'),
+            preserve_default=False,
+        ),
+        migrations.AlterModelOptions(
+            name='submission',
+            options={'verbose_name': 'Submission', 'verbose_name_plural': 'Submission Set'},
+        ),
+        migrations.AlterModelOptions(
+            name='submissiontype',
+            options={'verbose_name': 'SubmissionType', 'verbose_name_plural': 'SubmissionType Set'},
+        ),
+        migrations.RemoveField(
+            model_name='submissionstatus',
+            name='submission',
+        ),
+        migrations.RemoveField(
+            model_name='submissionstatus',
+            name='feedback_counter',
+        ),
+        migrations.AlterField(
+            model_name='submissionstatus',
+            name='status',
+            field=models.CharField(choices=[('R', 'READY'), ('CP', 'CORRECTION_IN_PROGRESS'), ('FL', 'FEEDBACK_LIMIT_REACHED'), ('RE', 'REVIEWED')], default='R', max_length=2),
+        ),
+        migrations.RenameField(
+            model_name='submissiontype',
+            old_name='correction_guideline',
+            new_name='possible_solution',
+        ),
+        migrations.AlterField(
+            model_name='submissionstatus',
+            name='status',
+            field=models.PositiveIntegerField(choices=[(0, 'READY'), (1, 'IN_PROGRESS'), (2, 'LIMIT_REACHED'), (3, 'REVIEWED')], default=0),
+        ),
+        migrations.RenameField(
+            model_name='submission',
+            old_name='submission_text',
+            new_name='text',
+        ),
+        migrations.RenameField(
+            model_name='submission',
+            old_name='submission_type',
+            new_name='type',
+        ),
+        migrations.RenameField(
+            model_name='submissiontype',
+            old_name='correct_solution',
+            new_name='task_description',
+        ),
+        migrations.AlterField(
+            model_name='submissionstatus',
+            name='status',
+            field=models.PositiveIntegerField(choices=[(0, 'READY'), (1, 'IN_PROGRESS'), (2, 'LIMIT_REACHED')], default=0),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='slug',
+            field=models.SlugField(editable=False, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='of_submission',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedback_list', to='core.Submission'),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='final',
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AlterField(
+            model_name='submissionstatus',
+            name='status',
+            field=models.PositiveIntegerField(choices=[(0, 'READY'), (1, 'LIMIT_REACHED')], default=0),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='score',
+            field=models.PositiveIntegerField(default=0, validators=[django.core.validators.MaxValueValidator(models.PositiveIntegerField(default=1000, editable=False)), django.core.validators.MinValueValidator(0)]),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='score',
+            field=models.PositiveIntegerField(default=0),
+        ),
+        migrations.RemoveField(
+            model_name='submissionstatus',
+            name='final_feedback',
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='slug',
+            field=models.SlugField(default=core.models.random_slug, editable=False, unique=True),
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='seen',
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AddField(
+            model_name='submissiontype',
+            name='correction_guideline',
+            field=models.TextField(default=2),
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='empty',
+            field=models.BooleanField(default=True),
+        ),
+        migrations.RemoveField(
+            model_name='feedback',
+            name='of_reviewer',
+        ),
+        migrations.AddField(
+            model_name='feedback',
+            name='of_reviewer',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviewed_submissions', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='of_submission',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedback', to='core.Submission'),
+        ),
+        migrations.AddField(
+            model_name='submission',
+            name='final_feedback',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Feedback'),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='of_submission',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedback_list', to='core.Submission'),
+        ),
+        migrations.AddField(
+            model_name='submissiontype',
+            name='slug',
+            field=models.SlugField(default=core.models.random_slug, editable=False, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='feedback',
+            name='slug',
+            field=models.SlugField(default=core.models.random_slug, editable=False, unique=True),
+        ),
+        migrations.DeleteModel(
+            name='SubmissionStatus',
+        ),
+    ]
diff --git a/core/migrations/0002_auto_20170303_1837.py b/core/migrations/0002_auto_20170303_1837.py
deleted file mode 100644
index 3c809d26..00000000
--- a/core/migrations/0002_auto_20170303_1837.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-03 18:37
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('core', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Feedback',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('score', models.PositiveIntegerField(default=0)),
-                ('text', models.TextField()),
-                ('of_reviewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviewd_submissions', to=settings.AUTH_USER_MODEL)),
-            ],
-            options={
-                'verbose_name': 'Feedback',
-                'verbose_name_plural': 'Feedbacks',
-            },
-        ),
-        migrations.CreateModel(
-            name='Student',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('matrikel_no', models.PositiveIntegerField(default=0, unique=True)),
-                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
-            ],
-        ),
-        migrations.CreateModel(
-            name='Submission',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('pre_corrections', models.TextField()),
-                ('student', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='core.Student')),
-            ],
-            options={
-                'verbose_name': 'Submission',
-                'verbose_name_plural': 'Submissions',
-            },
-        ),
-        migrations.AlterModelOptions(
-            name='submissiontype',
-            options={'verbose_name': 'SubmissionType', 'verbose_name_plural': 'SubmissionTypes'},
-        ),
-        migrations.AddField(
-            model_name='submissiontype',
-            name='full_score',
-            field=models.PositiveIntegerField(default=0),
-        ),
-        migrations.AddField(
-            model_name='submission',
-            name='submission_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submissions', to='core.SubmissionType'),
-        ),
-        migrations.AddField(
-            model_name='feedback',
-            name='of_submission',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Submission'),
-        ),
-        migrations.AddField(
-            model_name='feedback',
-            name='of_tutor',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='corrected_submissions', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/core/migrations/0027_submissiontype_description.py b/core/migrations/0002_auto_20170323_0026.py
similarity index 51%
rename from core/migrations/0027_submissiontype_description.py
rename to core/migrations/0002_auto_20170323_0026.py
index 3e2c9f1c..d8cd5fd0 100644
--- a/core/migrations/0027_submissiontype_description.py
+++ b/core/migrations/0002_auto_20170323_0026.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-14 17:23
+# Generated by Django 1.10.6 on 2017-03-23 00:26
 from __future__ import unicode_literals
 
 from django.db import migrations, models
@@ -8,14 +8,13 @@ from django.db import migrations, models
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('core', '0026_submission_seen'),
+        ('core', '0001_squashed_0034_auto_20170322_1304'),
     ]
 
     operations = [
-        migrations.AddField(
+        migrations.AlterField(
             model_name='submissiontype',
-            name='description',
-            field=models.TextField(default=2),
-            preserve_default=False,
+            name='correction_guideline',
+            field=models.TextField(),
         ),
     ]
diff --git a/core/migrations/0003_auto_20170303_2053.py b/core/migrations/0003_auto_20170303_2053.py
deleted file mode 100644
index 14198212..00000000
--- a/core/migrations/0003_auto_20170303_2053.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-03 20:53
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('core', '0002_auto_20170303_1837'),
-    ]
-
-    operations = [
-        migrations.AlterModelOptions(
-            name='feedback',
-            options={'verbose_name': 'Feedback', 'verbose_name_plural': 'Feedback Set'},
-        ),
-        migrations.AlterModelOptions(
-            name='student',
-            options={'verbose_name': 'Student', 'verbose_name_plural': 'Students'},
-        ),
-        migrations.AddField(
-            model_name='submission',
-            name='submission_text',
-            field=models.TextField(blank=True),
-        ),
-        migrations.RemoveField(
-            model_name='feedback',
-            name='of_reviewer',
-        ),
-        migrations.AddField(
-            model_name='feedback',
-            name='of_reviewer',
-            field=models.ManyToManyField(related_name='reviewd_submissions', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/core/migrations/0004_submission_final_feedback.py b/core/migrations/0004_submission_final_feedback.py
deleted file mode 100644
index d6cacba8..00000000
--- a/core/migrations/0004_submission_final_feedback.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 09:29
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0003_auto_20170303_2053'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='submission',
-            name='final_feedback',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Feedback'),
-        ),
-    ]
diff --git a/core/migrations/0005_auto_20170304_1200.py b/core/migrations/0005_auto_20170304_1200.py
deleted file mode 100644
index 513af0ba..00000000
--- a/core/migrations/0005_auto_20170304_1200.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 12:00
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0004_submission_final_feedback'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='submission',
-            name='pre_corrections',
-            field=models.TextField(blank=True),
-        ),
-        migrations.AlterField(
-            model_name='submission',
-            name='submission_text',
-            field=models.TextField(),
-        ),
-    ]
diff --git a/core/migrations/0006_auto_20170304_1523.py b/core/migrations/0006_auto_20170304_1523.py
deleted file mode 100644
index ff15887e..00000000
--- a/core/migrations/0006_auto_20170304_1523.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 15:23
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0005_auto_20170304_1200'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='feedback',
-            name='of_reviewer',
-            field=models.ManyToManyField(blank=True, related_name='reviewd_submissions', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/core/migrations/0007_feedback_slug.py b/core/migrations/0007_feedback_slug.py
deleted file mode 100644
index f0c12cb1..00000000
--- a/core/migrations/0007_feedback_slug.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 16:05
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0006_auto_20170304_1523'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='feedback',
-            name='slug',
-            field=models.SlugField(default=0),
-        ),
-    ]
diff --git a/core/migrations/0008_auto_20170304_1612.py b/core/migrations/0008_auto_20170304_1612.py
deleted file mode 100644
index c244e8a3..00000000
--- a/core/migrations/0008_auto_20170304_1612.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 16:12
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0007_feedback_slug'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='feedback',
-            name='slug',
-            field=models.SlugField(blank=True),
-        ),
-    ]
diff --git a/core/migrations/0009_auto_20170304_1614.py b/core/migrations/0009_auto_20170304_1614.py
deleted file mode 100644
index f998c665..00000000
--- a/core/migrations/0009_auto_20170304_1614.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 16:14
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0008_auto_20170304_1612'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='feedback',
-            name='slug',
-            field=models.SlugField(editable=False),
-        ),
-    ]
diff --git a/core/migrations/0010_auto_20170304_1741.py b/core/migrations/0010_auto_20170304_1741.py
deleted file mode 100644
index d1868e2b..00000000
--- a/core/migrations/0010_auto_20170304_1741.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-04 17:41
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0009_auto_20170304_1614'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='submission',
-            name='student',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Student'),
-        ),
-    ]
diff --git a/core/migrations/0011_auto_20170306_1327.py b/core/migrations/0011_auto_20170306_1327.py
deleted file mode 100644
index 8527f563..00000000
--- a/core/migrations/0011_auto_20170306_1327.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 13:27
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0010_auto_20170304_1741'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='SubmissionStatus',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('status', models.CharField(choices=[('NF', 'NO_FEEDBACK'), ('CP', 'CORRECTION IN PROGRESS'), ('FL', 'FEEDBACK_LIMIT_REACHED'), ('RE', 'REVIEWED')], default='NF', max_length=2)),
-                ('feedback_counter', models.PositiveIntegerField(default=0, editable=False)),
-                ('final_feedback', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Feedback')),
-            ],
-        ),
-        migrations.RemoveField(
-            model_name='submission',
-            name='final_feedback',
-        ),
-        migrations.AddField(
-            model_name='submissionstatus',
-            name='submission',
-            field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='core.Submission'),
-        ),
-    ]
diff --git a/core/migrations/0012_auto_20170306_1450.py b/core/migrations/0012_auto_20170306_1450.py
deleted file mode 100644
index 40238686..00000000
--- a/core/migrations/0012_auto_20170306_1450.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 14:50
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0011_auto_20170306_1327'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='submissionstatus',
-            name='status',
-            field=models.CharField(choices=[('R', 'READY'), ('CP', 'CORRECTION_IN_PROGRESS'), ('FL', 'FEEDBACK_LIMIT_REACHED'), ('RE', 'REVIEWED')], default=('R', 'READY'), max_length=2),
-        ),
-    ]
diff --git a/core/migrations/0013_auto_20170306_1452.py b/core/migrations/0013_auto_20170306_1452.py
deleted file mode 100644
index f3c20ee5..00000000
--- a/core/migrations/0013_auto_20170306_1452.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 14:52
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0012_auto_20170306_1450'),
-    ]
-
-    operations = [
-        migrations.AlterModelOptions(
-            name='submissionstatus',
-            options={'verbose_name': 'Submission Status', 'verbose_name_plural': 'Submission Status Set'},
-        ),
-    ]
diff --git a/core/migrations/0014_auto_20170306_1504.py b/core/migrations/0014_auto_20170306_1504.py
deleted file mode 100644
index 4e58b7f6..00000000
--- a/core/migrations/0014_auto_20170306_1504.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 15:04
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0013_auto_20170306_1452'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='submissiontype',
-            name='type_id',
-        ),
-        migrations.AddField(
-            model_name='submissiontype',
-            name='id',
-            field=models.AutoField(auto_created=True, default=123, primary_key=True, serialize=False, verbose_name='ID'),
-            preserve_default=False,
-        ),
-    ]
diff --git a/core/migrations/0015_auto_20170306_1525.py b/core/migrations/0015_auto_20170306_1525.py
deleted file mode 100644
index a46ff495..00000000
--- a/core/migrations/0015_auto_20170306_1525.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 15:25
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0014_auto_20170306_1504'),
-    ]
-
-    operations = [
-        migrations.AlterModelOptions(
-            name='student',
-            options={'verbose_name': 'Student', 'verbose_name_plural': 'Student Set'},
-        ),
-        migrations.AlterModelOptions(
-            name='submission',
-            options={'verbose_name': 'Submission', 'verbose_name_plural': 'Submission Set'},
-        ),
-        migrations.AlterModelOptions(
-            name='submissionstatus',
-            options={'verbose_name': 'Submission Status', 'verbose_name_plural': 'SubmissionStatus Set'},
-        ),
-        migrations.AlterModelOptions(
-            name='submissiontype',
-            options={'verbose_name': 'SubmissionType', 'verbose_name_plural': 'SubmissionType Set'},
-        ),
-        migrations.RemoveField(
-            model_name='submissionstatus',
-            name='submission',
-        ),
-        migrations.AddField(
-            model_name='submission',
-            name='submission_status',
-            field=models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.SubmissionStatus'),
-        ),
-    ]
diff --git a/core/migrations/0016_auto_20170306_1535.py b/core/migrations/0016_auto_20170306_1535.py
deleted file mode 100644
index 8af72380..00000000
--- a/core/migrations/0016_auto_20170306_1535.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 15:35
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0015_auto_20170306_1525'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='submission',
-            name='submission_status',
-            field=models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='submission', to='core.SubmissionStatus'),
-        ),
-    ]
diff --git a/core/migrations/0017_auto_20170306_1550.py b/core/migrations/0017_auto_20170306_1550.py
deleted file mode 100644
index 3d962950..00000000
--- a/core/migrations/0017_auto_20170306_1550.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 15:50
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0016_auto_20170306_1535'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='submissionstatus',
-            name='feedback_counter',
-            field=models.PositiveIntegerField(default=0),
-        ),
-        migrations.AlterField(
-            model_name='submissionstatus',
-            name='status',
-            field=models.CharField(choices=[('R', 'READY'), ('CP', 'CORRECTION_IN_PROGRESS'), ('FL', 'FEEDBACK_LIMIT_REACHED'), ('RE', 'REVIEWED')], default='R', max_length=2),
-        ),
-    ]
diff --git a/core/migrations/0018_auto_20170306_1605.py b/core/migrations/0018_auto_20170306_1605.py
deleted file mode 100644
index 9e1cbd3c..00000000
--- a/core/migrations/0018_auto_20170306_1605.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-06 16:05
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0017_auto_20170306_1550'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='submissiontype',
-            old_name='correction_guideline',
-            new_name='guideline',
-        ),
-        migrations.AlterField(
-            model_name='submissionstatus',
-            name='status',
-            field=models.PositiveIntegerField(choices=[(0, 'READY'), (1, 'IN_PROGRESS'), (2, 'LIMIT_REACHED'), (3, 'REVIEWED')], default=0),
-        ),
-    ]
diff --git a/core/migrations/0019_auto_20170307_1735.py b/core/migrations/0019_auto_20170307_1735.py
deleted file mode 100644
index 46804c6b..00000000
--- a/core/migrations/0019_auto_20170307_1735.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-07 17:35
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0018_auto_20170306_1605'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='submission',
-            old_name='submission_status',
-            new_name='status',
-        ),
-        migrations.RenameField(
-            model_name='submission',
-            old_name='submission_text',
-            new_name='text',
-        ),
-        migrations.RenameField(
-            model_name='submission',
-            old_name='submission_type',
-            new_name='type',
-        ),
-        migrations.RenameField(
-            model_name='submissiontype',
-            old_name='correct_solution',
-            new_name='solution',
-        ),
-        migrations.AlterField(
-            model_name='submissionstatus',
-            name='status',
-            field=models.PositiveIntegerField(choices=[(0, 'READY'), (1, 'IN_PROGRESS'), (2, 'LIMIT_REACHED')], default=0),
-        ),
-    ]
diff --git a/core/migrations/0020_auto_20170307_2031.py b/core/migrations/0020_auto_20170307_2031.py
deleted file mode 100644
index ce0a33eb..00000000
--- a/core/migrations/0020_auto_20170307_2031.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-07 20:31
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0019_auto_20170307_1735'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='feedback',
-            name='slug',
-            field=models.SlugField(editable=False, unique=True),
-        ),
-    ]
diff --git a/core/migrations/0021_auto_20170307_2122.py b/core/migrations/0021_auto_20170307_2122.py
deleted file mode 100644
index 1c92e01a..00000000
--- a/core/migrations/0021_auto_20170307_2122.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-07 21:22
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0020_auto_20170307_2031'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='submissionstatus',
-            name='feedback_counter',
-        ),
-        migrations.AlterField(
-            model_name='feedback',
-            name='of_submission',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedback_list', to='core.Submission'),
-        ),
-    ]
diff --git a/core/migrations/0022_auto_20170308_1439.py b/core/migrations/0022_auto_20170308_1439.py
deleted file mode 100644
index c67c8c74..00000000
--- a/core/migrations/0022_auto_20170308_1439.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-08 14:39
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0021_auto_20170307_2122'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='feedback',
-            name='final',
-            field=models.BooleanField(default=False),
-        ),
-        migrations.AlterField(
-            model_name='submissionstatus',
-            name='status',
-            field=models.PositiveIntegerField(choices=[(0, 'READY'), (1, 'LIMIT_REACHED')], default=0),
-        ),
-    ]
diff --git a/core/migrations/0023_auto_20170310_1422.py b/core/migrations/0023_auto_20170310_1422.py
deleted file mode 100644
index 0c08410b..00000000
--- a/core/migrations/0023_auto_20170310_1422.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-10 14:22
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0022_auto_20170308_1439'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='feedback',
-            name='max_score',
-            field=models.PositiveIntegerField(default=1000, editable=False),
-        ),
-        migrations.AlterField(
-            model_name='feedback',
-            name='score',
-            field=models.PositiveIntegerField(default=0, validators=[django.core.validators.MaxValueValidator(models.PositiveIntegerField(default=1000, editable=False)), django.core.validators.MinValueValidator(0)]),
-        ),
-    ]
diff --git a/core/migrations/0024_auto_20170310_1502.py b/core/migrations/0024_auto_20170310_1502.py
deleted file mode 100644
index f3df1f31..00000000
--- a/core/migrations/0024_auto_20170310_1502.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-10 15:02
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0023_auto_20170310_1422'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='feedback',
-            name='max_score',
-        ),
-        migrations.AlterField(
-            model_name='feedback',
-            name='score',
-            field=models.PositiveIntegerField(default=0),
-        ),
-    ]
diff --git a/core/migrations/0025_auto_20170311_1637.py b/core/migrations/0025_auto_20170311_1637.py
deleted file mode 100644
index c9aeac27..00000000
--- a/core/migrations/0025_auto_20170311_1637.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-11 16:37
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0024_auto_20170310_1502'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='submissionstatus',
-            name='final_feedback',
-        ),
-        migrations.AddField(
-            model_name='submission',
-            name='final_feedback',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Feedback'),
-        ),
-        migrations.AddField(
-            model_name='submission',
-            name='slug',
-            field=models.SlugField(default=23232323, editable=False, unique=True),
-            preserve_default=False,
-        ),
-    ]
diff --git a/core/migrations/0026_submission_seen.py b/core/migrations/0026_submission_seen.py
deleted file mode 100644
index 1cadbec0..00000000
--- a/core/migrations/0026_submission_seen.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-11 16:56
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0025_auto_20170311_1637'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='submission',
-            name='seen',
-            field=models.BooleanField(default=False),
-        ),
-    ]
diff --git a/core/migrations/0028_auto_20170314_1726.py b/core/migrations/0028_auto_20170314_1726.py
deleted file mode 100644
index 3993e2d9..00000000
--- a/core/migrations/0028_auto_20170314_1726.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-14 17:26
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0027_submissiontype_description'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='submissiontype',
-            old_name='description',
-            new_name='correction_guideline',
-        ),
-        migrations.RenameField(
-            model_name='submissiontype',
-            old_name='guideline',
-            new_name='possible_solution',
-        ),
-        migrations.RenameField(
-            model_name='submissiontype',
-            old_name='solution',
-            new_name='task_description',
-        ),
-    ]
diff --git a/core/migrations/0029_feedback_empty.py b/core/migrations/0029_feedback_empty.py
deleted file mode 100644
index c691b2a6..00000000
--- a/core/migrations/0029_feedback_empty.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-15 13:48
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0028_auto_20170314_1726'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='feedback',
-            name='empty',
-            field=models.BooleanField(default=True),
-        ),
-    ]
diff --git a/core/migrations/0030_auto_20170315_1444.py b/core/migrations/0030_auto_20170315_1444.py
deleted file mode 100644
index bbc48683..00000000
--- a/core/migrations/0030_auto_20170315_1444.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-15 14:44
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('core', '0029_feedback_empty'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='feedback',
-            name='of_reviewer',
-        ),
-        migrations.AddField(
-            model_name='feedback',
-            name='of_reviewer',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviewed_submissions', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/core/migrations/0031_auto_20170315_1603.py b/core/migrations/0031_auto_20170315_1603.py
deleted file mode 100644
index 0821ea8b..00000000
--- a/core/migrations/0031_auto_20170315_1603.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-15 16:03
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0030_auto_20170315_1444'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='submission',
-            name='final_feedback',
-        ),
-        migrations.AlterField(
-            model_name='feedback',
-            name='of_submission',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedback', to='core.Submission'),
-        ),
-    ]
diff --git a/core/migrations/0032_auto_20170315_1609.py b/core/migrations/0032_auto_20170315_1609.py
deleted file mode 100644
index 7842a7ed..00000000
--- a/core/migrations/0032_auto_20170315_1609.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-15 16:09
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0031_auto_20170315_1603'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='submission',
-            name='final_feedback',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.Feedback'),
-        ),
-        migrations.AlterField(
-            model_name='feedback',
-            name='of_submission',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feedback_list', to='core.Submission'),
-        ),
-    ]
diff --git a/core/migrations/0033_auto_20170321_2128.py b/core/migrations/0033_auto_20170321_2128.py
deleted file mode 100644
index 7b593a58..00000000
--- a/core/migrations/0033_auto_20170321_2128.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-21 21:28
-from __future__ import unicode_literals
-
-import core.models
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0032_auto_20170315_1609'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='submissiontype',
-            name='slug',
-            field=models.SlugField(default=core.models.random_slug, editable=False, unique=True),
-        ),
-        migrations.AlterField(
-            model_name='feedback',
-            name='slug',
-            field=models.SlugField(default=core.models.random_slug, editable=False, unique=True),
-        ),
-        migrations.AlterField(
-            model_name='submission',
-            name='slug',
-            field=models.SlugField(default=core.models.random_slug, editable=False, unique=True),
-        ),
-    ]
diff --git a/core/migrations/0034_auto_20170322_1304.py b/core/migrations/0034_auto_20170322_1304.py
deleted file mode 100644
index 18198605..00000000
--- a/core/migrations/0034_auto_20170322_1304.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.6 on 2017-03-22 13:04
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0033_auto_20170321_2128'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='submission',
-            name='status',
-        ),
-        migrations.DeleteModel(
-            name='SubmissionStatus',
-        ),
-    ]
diff --git a/core/models.py b/core/models.py
index 89f782d1..824a5f76 100644
--- a/core/models.py
+++ b/core/models.py
@@ -97,14 +97,13 @@ class Submission(models.Model):
         if unfinished:
             return
 
-
         ready = cls.objects.annotate(Count('feedback_list')).filter(
             feedback_list__count__lt=MAX_FEEDBACK_PER_SUBMISSION
         )
 
         # we do not want this tutor to correct the same submission twice
         if type_slug:
-            ready = cls.objects.filter(type__slug=type_slug)
+            ready = ready.filter(type__slug=type_slug)
         ready = ready.exclude(feedback_list__of_tutor=tutor)
         if not ready:
             return
diff --git a/core/views.py b/core/views.py
index f243de00..fa1ee4f6 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,35 +1,14 @@
 from django.contrib.auth import authenticate, login, logout
-from django.contrib.auth.decorators import login_required, user_passes_test
+from django.contrib.auth.decorators import login_required
 from django.contrib.auth.models import User
-from django.contrib import messages
-from django.http import Http404, HttpResponse, HttpResponseRedirect
+from django.db.models import Count
+from django.http import HttpResponse, HttpResponseRedirect
 from django.shortcuts import render
 from django.urls import reverse
-from django.db.models import Count
-from django.utils.decorators import method_decorator
-from django.views.generic import DetailView
-from django.views.generic.edit import UpdateView
 
-from core.forms import FeedbackForm
+from core.custom_annotations import group_required, in_groups
 from core.models import Feedback, Submission, SubmissionType
-from core.grady_speak import grady_says
-
-from random import choice
-
-# Create your views here.
-
-
-def in_groups(user, group_list):
-    return bool(user.groups.filter(name__in=group_list)) or user.is_superuser
-
-
-def group_required(*group_names):
-    """Requires user membership in at least one of the groups passed in."""
-    def _in_groups(u):
-        if u.is_authenticated():
-            return in_groups(u, group_names)
-    return user_passes_test(_in_groups)
-
+from core.viewset import *
 
 def index(request):
     context = {
@@ -86,7 +65,7 @@ def tutor_view(request):
         'submission_type_list': SubmissionType.objects.annotate(
             Count('submissions__feedback_list')).annotate(
             Count('submissions')
-            ).all(),
+        ).all(),
         'feedback_list': Feedback.objects.filter(of_tutor=request.user),
     }
     return render(request, 'core/tutor_startpage.html', context)
@@ -111,91 +90,3 @@ def reviewer_view(request):
     return render(request, 'core/reviewer_startpage.html', context)
 
 
-@group_required('Tutors')
-def create_feedback(request, type_slug=None):
-    # assign does nothing if tutor has unfinished feedback
-    Submission.assign_tutor(request.user, type_slug)
-    feedback = Feedback.tutor_unfinished_feedback(request.user)
-    if not feedback:
-        if type_slug:
-            messages.info(request, "No more submissions of this type available.")
-        else:
-            messages.success(request, "Well done! There is no more work to do.")
-        return HttpResponseRedirect(reverse('start'))
-    return HttpResponseRedirect(reverse('FeedbackEdit', args=(feedback.slug,)))
-
-
-@group_required('Tutors', 'Reviewers')
-def delete_feedback(request, feedback_slug):
-    """ Hook to ensure object is owned by request.user. """
-    instance = Feedback.objects.get(slug=feedback_slug)
-    if instance.of_tutor != request.user and not in_groups(request.user, ('Reviewers', )):
-        raise Http404
-    instance.delete()
-    return HttpResponseRedirect(reverse('start'))
-
-
-@group_required('Reviewers')
-def markfinal_feedback(request, feedback_slug):
-    instance = Feedback.objects.get(slug=feedback_slug)
-    instance.finalize_feedback(request.user)
-    return HttpResponseRedirect(reverse('start'))
-
-
-@group_required('Reviewers')
-def markunfinal_feedback(request, feedback_slug):
-    instance = Feedback.objects.get(slug=feedback_slug)
-    instance.unfinalize_feedback()
-    return HttpResponseRedirect(reverse('start'))
-
-
-class FeedbackEdit(UpdateView):
-
-    """docstring for FeedbackCreate"""
-
-    form_class = FeedbackForm
-    template_name = 'core/feedback_form.html'
-    success_url = '/start/'
-
-    @method_decorator(group_required('Tutors', 'Reviewers'))
-    def dispatch(self, *args, **kwargs):
-        return super(FeedbackEdit, self).dispatch(*args, **kwargs)
-
-    def get_object(self):
-        instance = Feedback.objects.get(slug=self.kwargs['feedback_slug'])
-        if instance.of_tutor != self.request.user and not in_groups(self.request.user, ('Reviewers', )):
-            raise Http404
-        return instance
-
-    def form_valid(self, form):
-        """
-        If the form is valid, redirect to the supplied URL.
-        """
-        if form.is_valid():
-            form.instance.empty = False
-            form.save()
-        if 'Next' in self.request.POST['update']:
-            return HttpResponseRedirect(reverse('CreateFeedbackForType', args=(form.instance.of_submission.type.slug,)))
-        return HttpResponseRedirect(self.get_success_url())
-
-    def get_context_data(self, **kwargs):
-        context = super(FeedbackEdit, self).get_context_data(**kwargs)
-        context['grady_says'] = choice(grady_says)
-        return context
-
-
-class SubmissionView(DetailView):
-
-    template_name = 'core/submission_view.html'
-    model = Submission
-
-    @method_decorator(group_required('Reviewers', 'Students'))
-    def dispatch(self, *args, **kwargs):
-        return super(SubmissionView, self).dispatch(*args, **kwargs)
-
-    def get_object(self):
-        obj = Submission.objects.get(slug=self.kwargs['slug'])
-        if obj.final_feedback:
-            obj.seen = True
-            obj.save()
-        return obj
diff --git a/core/viewset/__init__.py b/core/viewset/__init__.py
new file mode 100644
index 00000000..fa4ec8df
--- /dev/null
+++ b/core/viewset/__init__.py
@@ -0,0 +1,2 @@
+from .feedback import *
+from .submission import *
diff --git a/core/viewset/feedback.py b/core/viewset/feedback.py
new file mode 100644
index 00000000..554321ed
--- /dev/null
+++ b/core/viewset/feedback.py
@@ -0,0 +1,87 @@
+from random import choice
+
+from django.contrib import messages
+from django.http import Http404, HttpResponseRedirect
+from django.urls import reverse
+from django.utils.decorators import method_decorator
+from django.views.generic.edit import UpdateView
+
+from core.custom_annotations import group_required, in_groups
+from core.forms import FeedbackForm
+from core.grady_speak import grady_says
+from core.models import Feedback, Submission, SubmissionType
+
+
+@group_required('Tutors')
+def create_feedback(request, type_slug=None):
+    # assign does nothing if tutor has unfinished feedback
+    Submission.assign_tutor(request.user, type_slug)
+    feedback = Feedback.tutor_unfinished_feedback(request.user)
+    if not feedback:
+        if type_slug:
+            messages.info(request, "No more submissions of type '%s' available." %
+                          SubmissionType.objects.get(slug=type_slug))
+        else:
+            messages.success(
+                request, "Well done! There is no more work to do.")
+        return HttpResponseRedirect(reverse('start'))
+    return HttpResponseRedirect(reverse('FeedbackEdit', args=(feedback.slug,)))
+
+
+@group_required('Tutors', 'Reviewers')
+def delete_feedback(request, feedback_slug):
+    """ Hook to ensure object is owned by request.user. """
+    instance = Feedback.objects.get(slug=feedback_slug)
+    if instance.of_tutor != request.user and not in_groups(request.user, ('Reviewers', )):
+        raise Http404
+    instance.delete()
+    return HttpResponseRedirect(reverse('start'))
+
+
+@group_required('Reviewers')
+def markfinal_feedback(request, feedback_slug):
+    instance = Feedback.objects.get(slug=feedback_slug)
+    instance.finalize_feedback(request.user)
+    return HttpResponseRedirect(reverse('start'))
+
+
+@group_required('Reviewers')
+def markunfinal_feedback(request, feedback_slug):
+    instance = Feedback.objects.get(slug=feedback_slug)
+    instance.unfinalize_feedback()
+    return HttpResponseRedirect(reverse('start'))
+
+
+class FeedbackEdit(UpdateView):
+
+    """docstring for FeedbackCreate"""
+
+    form_class = FeedbackForm
+    template_name = 'core/feedback_form.html'
+    success_url = '/start/'
+
+    @method_decorator(group_required('Tutors', 'Reviewers'))
+    def dispatch(self, *args, **kwargs):
+        return super(FeedbackEdit, self).dispatch(*args, **kwargs)
+
+    def get_object(self):
+        instance = Feedback.objects.get(slug=self.kwargs['feedback_slug'])
+        if instance.of_tutor != self.request.user and not in_groups(self.request.user, ('Reviewers', )):
+            raise Http404
+        return instance
+
+    def form_valid(self, form):
+        """
+        If the form is valid, redirect to the supplied URL.
+        """
+        if form.is_valid():
+            form.instance.empty = False
+            form.save()
+        if 'Next' in self.request.POST['update']:
+            return HttpResponseRedirect(reverse('CreateFeedbackForType', args=(form.instance.of_submission.type.slug,)))
+        return HttpResponseRedirect(self.get_success_url())
+
+    def get_context_data(self, **kwargs):
+        context = super(FeedbackEdit, self).get_context_data(**kwargs)
+        context['grady_says'] = choice(grady_says)
+        return context
diff --git a/core/viewset/submission.py b/core/viewset/submission.py
new file mode 100644
index 00000000..129e1f85
--- /dev/null
+++ b/core/viewset/submission.py
@@ -0,0 +1,22 @@
+from django.utils.decorators import method_decorator
+from django.views.generic import DetailView
+
+from core.custom_annotations import group_required
+from core.models import Submission
+
+
+class SubmissionView(DetailView):
+
+    template_name = 'core/submission_view.html'
+    model = Submission
+
+    @method_decorator(group_required('Reviewers', 'Students'))
+    def dispatch(self, *args, **kwargs):
+        return super(SubmissionView, self).dispatch(*args, **kwargs)
+
+    def get_object(self):
+        obj = Submission.objects.get(slug=self.kwargs['slug'])
+        if obj.final_feedback:
+            obj.seen = True
+            obj.save()
+        return obj
-- 
GitLab