diff --git a/.gitignore b/.gitignore
index 9f0242823d723af98a6a9c19b349f948fd7f31de..257b15a07d5968520df7f8d2e42835e41ed6d12f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,4 @@ tests/.coverage
 build/
 tests/report/
 db.sqlite3
-env-grady/
\ No newline at end of file
+env-grady/
diff --git a/core/__init__.py b/core/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..17acc4cd4393f0d1b62100ecfb5ed2a5db34e814 100644
--- a/core/__init__.py
+++ b/core/__init__.py
@@ -0,0 +1 @@
+default_app_config = 'core.apps.CoreConfig'
diff --git a/core/apps.py b/core/apps.py
index 26f78a8e673340121f68a92930e2830bc58d269d..089650b78caaed54d112d93f4694d1c73167bdb6 100644
--- a/core/apps.py
+++ b/core/apps.py
@@ -3,3 +3,4 @@ from django.apps import AppConfig
 
 class CoreConfig(AppConfig):
     name = 'core'
+    verbose_name = 'where everything comes together'
diff --git a/core/fixtures/initial_data.json b/core/fixtures/initial_data.json
new file mode 100644
index 0000000000000000000000000000000000000000..87a57244ae962bb23f694b0623d2cc369b2a2eef
--- /dev/null
+++ b/core/fixtures/initial_data.json
@@ -0,0 +1,44 @@
+[
+    {
+        "fields": {
+            "correct_solution": "Das geht dich gar nichts an.",
+            "correction_guideline": "Mach das mal so und so.",
+            "full_score": 10,
+            "name": "Irgendwas Sortieren"
+        },
+        "model": "core.submissiontype",
+        "pk": "123"
+    },
+    {
+        "fields": {
+            "matrikel_no": 21999999,
+            "user": 17
+        },
+        "model": "core.student",
+        "pk": 1
+    },
+    {
+        "fields": {
+            "final_feedback": null,
+            "pre_corrections": "Was das System halt so kann.",
+            "student": 1,
+            "submission_text": "class Uhrzeit implements Comparable<Uhrzeit> {\r\n    private int stunde; // Stundenangabe\r\n    private int minute; // Minutenangabe\r\n    public Uhrzeit(int stunde, int minute) { // nur sinnvolle Zeitangaben ..\r\n        if ( 0 <= stunde && stunde <= 23 &&  // .. behandeln\r\n                0 <= minute && minute <= 59) {\r\n            this.stunde = stunde;   // Stundenangabe zuweisen\r\n            this.minute = minute;   // Minutenangabe zuweisen\r\n        } else throw new RuntimeException(\"UngÞltige Zeitangabe!\");\r\n    }\r\n\r\n    public String toString() { // String-Darstellung in der Form:\r\n        return stunde + \" Uhr und \" + minute + \" Minute(n)\"; // <Stundenangabe> Uhr und <Minutenangabe> Minuten\r\n    }\r\n}",
+            "submission_type": "123"
+        },
+        "model": "core.submission",
+        "pk": 1
+    },
+    {
+        "fields": {
+            "of_reviewer": [
+                16
+            ],
+            "of_submission": 1,
+            "of_tutor": 15,
+            "score": 10,
+            "text": "You did a good job"
+        },
+        "model": "core.feedback",
+        "pk": 1
+    }
+]
diff --git a/core/fixtures/load_inital.json b/core/fixtures/load_inital.json
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/forms.py b/core/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e1c0dba53308bd0920a4502880519682b04a3bf
--- /dev/null
+++ b/core/forms.py
@@ -0,0 +1,6 @@
+from django import forms
+from core.models import Feedback, Submission
+
+class CorrectionForm(forms.Form):
+    comments = forms.TextField()
+    score = forms.PositiveIntegerField(initial=0)
diff --git a/core/migrations/0003_auto_20170303_2053.py b/core/migrations/0003_auto_20170303_2053.py
new file mode 100644
index 0000000000000000000000000000000000000000..1419821275dd0c81f1c859a98d4f5323874389dd
--- /dev/null
+++ b/core/migrations/0003_auto_20170303_2053.py
@@ -0,0 +1,39 @@
+# -*- 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
new file mode 100644
index 0000000000000000000000000000000000000000..d606c4772ba3607908c00a38ae5e7626c4300a3c
--- /dev/null
+++ b/core/migrations/0004_submission_final_feedback.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-03-04 09:29
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+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
new file mode 100644
index 0000000000000000000000000000000000000000..513af0ba0557afb16a68436f54cc356a6a7c2f37
--- /dev/null
+++ b/core/migrations/0005_auto_20170304_1200.py
@@ -0,0 +1,25 @@
+# -*- 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
new file mode 100644
index 0000000000000000000000000000000000000000..ff15887e88d2892764291d2d12b70ebd925a3f3c
--- /dev/null
+++ b/core/migrations/0006_auto_20170304_1523.py
@@ -0,0 +1,21 @@
+# -*- 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
new file mode 100644
index 0000000000000000000000000000000000000000..f0c12cb17e360b6ee18cc69d8b3e5630873ea4dd
--- /dev/null
+++ b/core/migrations/0007_feedback_slug.py
@@ -0,0 +1,20 @@
+# -*- 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
new file mode 100644
index 0000000000000000000000000000000000000000..c244e8a3affaa9da478db5bbae9f271b685e50b6
--- /dev/null
+++ b/core/migrations/0008_auto_20170304_1612.py
@@ -0,0 +1,20 @@
+# -*- 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
new file mode 100644
index 0000000000000000000000000000000000000000..f998c6653b13f7923d92543616567d8062332020
--- /dev/null
+++ b/core/migrations/0009_auto_20170304_1614.py
@@ -0,0 +1,20 @@
+# -*- 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/models.py b/core/models.py
index 9fb8e8849728268cc2579f7aaf1d2d068fd30b08..ea22bdb8c3238b9aabd99fbe62482b241af39d22 100644
--- a/core/models.py
+++ b/core/models.py
@@ -1,9 +1,11 @@
+from random import sample
+from string import ascii_lowercase
+
 from django.db import models
 from django.contrib.auth.models import User
+from django.template.defaultfilters import slugify
 
 
-# Create your models here.
-
 class SubmissionType(models.Model):
 
     # Fields
@@ -22,19 +24,28 @@ class SubmissionType(models.Model):
 
 
 class Student(models.Model):
-    user = models.OneToOneField(User, on_delete=models.CASCADE)
+
+    # Fields
+    user = models.OneToOneField(
+        User, on_delete=models.CASCADE, limit_choices_to={'groups__name': 'Students'})
     matrikel_no = models.PositiveIntegerField(unique=True, default=0)
 
     class Meta:
         verbose_name = "Student"
         verbose_name_plural = "Students"
 
+    def __str__(self):
+        return "{} ({})".format(self.user.username, self.matrikel_no)
+
 
 class Submission(models.Model):
 
     # Fields
-    pre_corrections = models.TextField()
-    submission_type = models.ForeignKey(SubmissionType, related_name='submissions')
+    submission_type = models.ForeignKey(
+        SubmissionType, related_name='submissions')
+    submission_text = models.TextField()
+    pre_corrections = models.TextField(blank=True)
+    final_feedback = models.OneToOneField('Feedback', null=True, blank=True)
     student = models.OneToOneField(Student)
 
     class Meta:
@@ -42,24 +53,41 @@ class Submission(models.Model):
         verbose_name_plural = "Submissions"
 
     def __str__(self):
-        pass
+        return "Submission of type '{}' from Student '{}'".format(
+            self.submission_type,
+            self.student
+        )
 
 
 class Feedback(models.Model):
 
-    # fields
+    # Fields
     score = models.PositiveIntegerField(default=0)
     text = models.TextField()
     of_submission = models.ForeignKey(Submission)
-    of_tutor = models.ForeignKey(User, related_name='corrected_submissions')
-    of_reviewer = models.ForeignKey(User, related_name='reviewd_submissions')
+    of_tutor = models.ForeignKey(
+        User,
+        related_name='corrected_submissions',
+        limit_choices_to={'groups__name': 'Tutors'}
+    )
+    of_reviewer = models.ManyToManyField(
+        User,
+        related_name='reviewd_submissions',
+        limit_choices_to={'groups__name': 'Reviewers'},
+        blank=True
+    )
+    slug = models.SlugField(editable=False)
 
     class Meta:
         verbose_name = "Feedback"
         verbose_name_plural = "Feedback Set"
 
+    def save(self, *args, **kwargs):
+        self.slug = ''.join(sample(ascii_lowercase, 16))
+        super(Feedback, self).save(*args, **kwargs)
+
     def __str__(self):
-        pass
+        return 'Feedback for {}'.format(self.of_submission)
 
     def is_full_score(self):
         return of_submission.full_score == score
diff --git a/core/templates/core/feedback.html b/core/templates/core/feedback.html
new file mode 100644
index 0000000000000000000000000000000000000000..09062b36f14f8c2add8178deafdd08a9fa7142be
--- /dev/null
+++ b/core/templates/core/feedback.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Feedback View</title>
+</head>
+<body>
+    <h1>This is the view for {{ feedback }}</h1>
+
+    <div>
+        <h2>The student {{ feedback.of_submission.student }} has submitted:</h2>
+        <pre>{{ feedback.of_submission.submission_text }}</pre>
+        <h2> {{ feedback.of_tutor }} has created this feedback:</h2>
+        <pre>{{ feedback.text }}</pre>
+        <p>The final score based on this feedback is <code>{{ feedback.score }}</code>. </p>
+    </div>
+
+    {% if not feedback.of_reviwer %}
+        <h2>Nobody reviewed this feedback so far</h2>
+    {% endif %}
+</body>
+</html>
diff --git a/core/templates/core/index.html b/core/templates/core/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..7832b53516816ac7ea2371d8b8370becddb0ec67
--- /dev/null
+++ b/core/templates/core/index.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+
+    <head>
+        <title>Rango</title>
+    </head>
+
+    <body>
+        <h1>All the types</h1>
+
+        {% for subm in submission_t %}
+            <h2> {{ subm }}</h2>
+            <ul>
+                {% for s in submissions %}
+                    <li> {{ s }} </li>
+                {% endfor %}
+            </ul>
+        {% endfor %}
+        <strong>{{ boldmessage }}</strong><br>
+    </body>
+
+</html>
diff --git a/core/templates/core/login.html b/core/templates/core/login.html
new file mode 100644
index 0000000000000000000000000000000000000000..81e9b253c184c3b72d3a27bf25e9f88009871aae
--- /dev/null
+++ b/core/templates/core/login.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Grady -- Login</title>
+</head>
+<body>
+    <h1>Welcome to Correction Hell</h1>
+
+    <form id="login_form" method="post" action="/login/">
+        {% csrf_token %}
+        <p>Username: <input type="text" name="username" value="" size="30"></p>
+        <p>Passwort: <input type="password" name="password" value="" size="30"></p>
+        <p><input type="submit" value="submit" /></p>
+    </form>
+</body>
+</html>
diff --git a/core/templates/core/tutor_startpage.html b/core/templates/core/tutor_startpage.html
new file mode 100644
index 0000000000000000000000000000000000000000..c79ab959e5d013e6e985a62dda98ecf29338d4ff
--- /dev/null
+++ b/core/templates/core/tutor_startpage.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Tutor Startpage</title>
+</head>
+<body>
+    <h1>Hello {{tutor_name}}! </h1>
+
+    {% if feedback_list|length == 0 %}
+        <h2>You havn't provided any feedback yet. Sad. Get to work!</h2>
+    {% else %}
+        {% if feedback_list|length == 1 %}
+            <h2>So far you have provieded one constribution </h2>
+        {% else %}
+            <h2>So far you have provided {{feedback_list|length}} constributions.</h2>
+        {% endif %}
+        <ul>
+        {% for feedback in feedback_list %}
+            <li> <a href="/feedback/{{ feedback.slug }}/"> {{ feedback }}</a> </li>
+        {% endfor %}
+        </ul>
+    {% endif %}
+
+    <p><a href="/logout/">Logout</a></p>
+</body>
+</html>
diff --git a/core/urls.py b/core/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..3c162974d5d8c3979f4b5c5957e9b2af94fed605
--- /dev/null
+++ b/core/urls.py
@@ -0,0 +1,10 @@
+from django.conf.urls import url
+from core import views
+
+urlpatterns = [
+    url(r'^$', views.index, name='index'),
+    url(r'^login/$', views.user_login, name='login'),
+    url(r'^logout/$', views.user_logout, name='logout'),
+    url(r'^tutor/$', views.tutor_startpage, name='tutor'),
+    url(r'^feedback/(?P<feedback_slug>\w+)/$', views.feedback, name='feedback'),
+]
diff --git a/core/views.py b/core/views.py
index 27cdb63bf2c6062ddf98320c2178a012da2b8bfb..fe3da9cb27132943b12d9fb7020af7b548819014 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,4 +1,77 @@
+from django.contrib.auth import authenticate, login, logout
+from django.contrib.auth.models import User, Group
+from django.contrib.auth.decorators import user_passes_test, login_required
+from django.http import HttpResponseRedirect, HttpResponse
 from django.shortcuts import render
 
+from core.models import Submission, SubmissionType, Feedback
+
+
 # Create your views here.
 
+def index(request):
+    context = {
+        'boldmessage': 'Delbert Grady says hey there world!',
+        'submission_t': SubmissionType.objects.all(),
+        'submissions': Submission.objects.all(),
+    }
+    return render(request, 'core/index.html', context)
+
+
+def delegate_user(user) -> str:
+    if user.groups.filter(name='Tutors').exists():
+        return '/tutor/'
+    if user.groups.filter(name='Reviewers').exists():
+        return '/reviewers/'
+    if user.groups.filter(name='Students').exists():
+        return '/students/'
+
+
+def user_login(request):
+
+    if request.method == 'POST':
+        username = request.POST['username']
+        password = request.POST['password']
+
+        user = authenticate(username=username, password=password)
+
+        if user is not None:
+            if user.is_active:
+                login(request, user)
+                return HttpResponseRedirect(delegate_user(user))
+            else:
+                return HttpResponse("Your Grady account is disabled.")
+
+        else:
+            # Bad login details were provided. So we can't log the user in.
+            print("Invalid login details: {0}, {1}".format(username, password))
+            return HttpResponse("Invalid login details supplied.")
+    else:
+        return render(request, 'core/login.html', {})
+
+
+@login_required
+def user_logout(request):
+    logout(request)
+    return HttpResponseRedirect('/login/')
+
+
+def is_tutor(user):
+    group = Group.objects.get(name='Tutors')
+    return group in user.groups.all()
+
+
+@user_passes_test(is_tutor, login_url='/login/')
+def tutor_startpage(request):
+    context = {
+        'tutor_name': request.user.username,
+        'feedback_list': Feedback.objects.filter(of_tutor=request.user)
+    }
+    return render(request, 'core/tutor_startpage.html', context)
+
+@user_passes_test(is_tutor, login_url='/login/')
+def feedback(request, feedback_slug):
+    context = {'feedback': Feedback.objects.get(slug=feedback_slug)}
+
+    # Go render the response and return it to the client.
+    return render(request, 'core/feedback.html', context)
diff --git a/grady/settings.py b/grady/settings.py
index 552b307ed219ca1f1a02d65b8a832bfcb366ca17..528a47ed99ed50ec5e172e9ade78ced181328833 100644
--- a/grady/settings.py
+++ b/grady/settings.py
@@ -27,7 +27,6 @@ DEBUG = True
 
 ALLOWED_HOSTS = []
 
-
 # Application definition
 
 INSTALLED_APPS = [
@@ -37,6 +36,7 @@ INSTALLED_APPS = [
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
+    'django_extensions',
     'core',
 ]
 
@@ -119,3 +119,10 @@ USE_TZ = True
 # https://docs.djangoproject.com/en/1.10/howto/static-files/
 
 STATIC_URL = '/static/'
+
+FIXTURE_DIRS = ['/core/fixtures/']
+
+GRAPH_MODELS = {
+  'all_applications': True,
+  'group_models': True,
+}
diff --git a/grady/urls.py b/grady/urls.py
index 5f087860fede9591fa373a4a66c2d85de8546007..1ccdb005a411b0e6d85de76dd4a0be99e5402b2d 100644
--- a/grady/urls.py
+++ b/grady/urls.py
@@ -13,9 +13,10 @@ Including another URLconf
     1. Import the include() function: from django.conf.urls import url, include
     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
 """
-from django.conf.urls import url
+from django.conf.urls import url, include
 from django.contrib import admin
 
 urlpatterns = [
     url(r'^admin/', admin.site.urls),
+    url(r'^', include('core.urls'))
 ]
diff --git a/populatedb.py b/populatedb.py
new file mode 100644
index 0000000000000000000000000000000000000000..086d2cc115f480a6eefea9f938d22626f62881db
--- /dev/null
+++ b/populatedb.py
@@ -0,0 +1,54 @@
+import os, random
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'grady.settings')
+
+import django
+django.setup()
+
+from core.models import Submission, SubmissionType, Student, Feedback
+from django.contrib.auth.models import User, Group
+
+
+def populate():
+    if User.objects.get(username='doncamillo'):
+        print("Was already created. Aborting...")
+        return
+
+    student_group = add_group('Students')
+    tutor_group = add_group('Tutors')
+    reviewer_group = add_group('Reviewers')
+
+    add_user('Test_Tutor', tutor_group)
+    add_user('Test_Reviewer', reviewer_group)
+    add_student('Test_Student1')
+    add_student('Test_Student2')
+    add_student('Test_Student3')
+
+
+def add_submission_type(name, score, solution):
+    SubmissionType(name=name, score=score)
+
+def add_student(name):
+    student_group = Group.objects.get(name='Students')
+    student_user = add_user(name, student_group)
+    student = Student(user=student_user, matrikel_no=20000000 + random.randrange(21343))
+    student.save()
+
+
+def add_user(username, group, password='password'):
+    user, _ = User.objects.get_or_create(username=username)
+    user.set_password(password)
+    group.user_set.add(user)
+    print("- Created user {} and added him to group {}".format(user, group))
+    user.save()
+    return user
+
+
+def add_group(group_name):
+    group, _ = Group.objects.get_or_create(name=group_name)
+    group.save()
+    return group
+
+# Start execution here!
+if __name__ == '__main__':
+    print("Starting population script...")
+    populate()