diff --git a/unisportomat/quiz/admin.py b/unisportomat/quiz/admin.py
index 8c38f3f3dad51e4585f3984282c2a4bec5349c1e..83f1f9ab498f769dee9241a828b24bfb45b2b66a 100644
--- a/unisportomat/quiz/admin.py
+++ b/unisportomat/quiz/admin.py
@@ -1,3 +1,7 @@
 from django.contrib import admin
 
 # Register your models here.
+from .models import Sport
+
+admin.site.register(Sport)
+
diff --git a/unisportomat/quiz/migrations/0001_refactor_sport_and_add_criteria.py b/unisportomat/quiz/migrations/0001_refactor_sport_and_add_criteria.py
new file mode 100644
index 0000000000000000000000000000000000000000..31b661347cd7db1b1069ce60d1be68b294b92974
--- /dev/null
+++ b/unisportomat/quiz/migrations/0001_refactor_sport_and_add_criteria.py
@@ -0,0 +1,92 @@
+# Generated by Django 3.2 on 2021-05-20 11:07
+
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    replaces = [('quiz', '0001_initial'), ('quiz', '0002_wissensnack_text'), ('quiz', '0003_auto_20210517_1437'), ('quiz', '0004_criterion'), ('quiz', '0005_auto_20210517_1520'), ('quiz', '0006_rename_criterion_ratings_sport_criteria_ratings'), ('quiz', '0007_auto_20210518_1521'), ('quiz', '0008_alter_sport_url')]
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Sport',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.TextField(choices=[('After Work Fitness', 'After Work Fitness'), ('Ballett', 'Ballett'), ('Basketball', 'Basketball'), ('Beachvolleyball', 'Beachvolleyball'), ('Bouldern', 'Bouldern'), ('Drachenfliegen', 'Drachenfliegen'), ('Functional Fitness', 'Functional Fitness'), ('Gerätturnen', 'Gerätturnen'), ('HIIT', 'HIIT'), ('Karate', 'Karate'), ('Kickboxen', 'Kickboxen'), ('Laufen', 'Laufen'), ('Pilates', 'Pilates'), ('Qigong', 'Qigong'), ('Rückenfit', 'Rückenfit'), ('Segeln Sportbootführerschein', 'Segeln Sportbootführerschein'), ('Skilanglauf & Schneeschuhwandern', 'Skilanglauf & Schneeschuhwandern'), ('Sweat & Relax', 'Sweat & Relax'), ('Tennis', 'Tennis'), ('Ultimate Frisbee', 'Ultimate Frisbee'), ('Yoga', 'Yoga')])),
+                ('field', models.CharField(choices=[('indoor', 'indoor'), ('outdoor', 'outdoor')], default='outdoor', max_length=50)),
+                ('einzelsport', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)], default=1)),
+                ('mannschaftssport', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)], default=1)),
+                ('ausdauer', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)], default=1)),
+                ('kraft', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)], default=1)),
+                ('kampfsport', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)], default=1)),
+                ('technischakrobatisch', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)], default=1)),
+                ('url', models.TextField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Criterion',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.TextField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='CriterionRating',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('rating', models.IntegerField(validators=[django.core.validators.MaxValueValidator(10), django.core.validators.MinValueValidator(0)])),
+                ('criterion', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quiz.criterion')),
+                ('sport', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quiz.sport')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='sport',
+            name='criteria_ratings',
+            field=models.ManyToManyField(through='quiz.CriterionRating', to='quiz.Criterion'),
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='ausdauer',
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='einzelsport',
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='field',
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='kampfsport',
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='kraft',
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='mannschaftssport',
+        ),
+        migrations.RemoveField(
+            model_name='sport',
+            name='technischakrobatisch',
+        ),
+        migrations.AlterField(
+            model_name='sport',
+            name='name',
+            field=models.TextField(),
+        ),
+        migrations.AlterField(
+            model_name='sport',
+            name='url',
+            field=models.URLField(),
+        ),
+    ]
diff --git a/unisportomat/quiz/models.py b/unisportomat/quiz/models.py
index 630c195ac0d3480e2c197f3c24d71ca1c6a2f2e9..a3b25fde270a944af9ecd5d8a89ad8a129c2c66e 100644
--- a/unisportomat/quiz/models.py
+++ b/unisportomat/quiz/models.py
@@ -1,65 +1,56 @@
-from django.db import models
-
-# Create your models here.
-
-class Sport(models.Model):
-    bewertungsskala = []
-    for i in range(1,11):
-        bewertungsskala.append((i,i))
-
-    sportart_list = [
-        ('After Work Fitness','After Work Fitness'),
-        ('Ballett','Ballett'),
-        ('Basketball','Basketball'),
-        ('Beachvolleyball','Beachvolleyball'),
-        ('Bouldern','Bouldern'),
-        ('Drachenfliegen','Drachenfliegen'),
-        ('Functional Fitness','Functional Fitness'),
-        ('Gerätturnen','Gerätturnen'),
-        ('HIIT','HIIT'),
-        ('Karate','Karate'),
-        ('Kickboxen','Kickboxen'),
-        ('Laufen','Laufen'),
-        ('Pilates','Pilates'),
-        ('Qigong','Qigong'),
-        ('Rückenfit','Rückenfit'),
-        ('Segeln Sportbootführerschein','Segeln Sportbootführerschein'),
-        ('Skilanglauf & Schneeschuhwandern','Skilanglauf & Schneeschuhwandern'),
-        ('Sweat & Relax','Sweat & Relax'),
-        ('Tennis','Tennis'),
-        ('Ultimate Frisbee','Ultimate Frisbee'),
-        ('Yoga','Yoga')
-
-    ]
+""" Model definitions for the quiz """
 
-    fields = [
-        ('indoor','indoor'),
-        ('outdoor','outdoor')
-    ]
-
-    sportart                = models.TextField(choices=sportart_list)
-    field                   = models.CharField(default='outdoor',max_length=50,choices=fields)
-    einzelsport             = models.IntegerField(default=1,choices=bewertungsskala)
-    mannschaftssport        = models.IntegerField(default=1,choices=bewertungsskala)
-    ausdauer                = models.IntegerField(default=1,choices=bewertungsskala)
-    kraft                   = models.IntegerField(default=1,choices=bewertungsskala)
-    kampfsport              = models.IntegerField(default=1,choices=bewertungsskala)
-    technischakrobatisch    = models.IntegerField(default=1,choices=bewertungsskala)
-    url                     = models.TextField()#URLField liefert Error
-    
-    
-    def __str__(self):
-        return self.sportart
+from django.core.validators import MaxValueValidator, MinValueValidator
+from django.db import models
 
-#fragen-class
-class Question(models.Model):
-    pass
 
+class CriterionRating(models.Model):
+    """
+    This is the relation between Sport and Criterion.
+    You can use it to add a rating for a specific criterion to a sport.
+    To see it's usage check Sport.rate() and Sport.get_rating()
+    """
 
+    rating = models.IntegerField(
+        validators=[MaxValueValidator(10), MinValueValidator(1)]
+    )
+    criterion = models.ForeignKey("Criterion", on_delete=models.CASCADE)
+    sport = models.ForeignKey("Sport", on_delete=models.CASCADE)
 
-#Wissensnack
-class Wissensnack(models.Model):
-    pass
 
+class Sport(models.Model):
+    """
+    Defines a Sport with name, url that leads to the booking page.
+    A sport includes ratings for all criterions.
+    (e.g. How much it corresponds to the criterion "Martial Arts")
+    """
 
+    name = models.TextField()
+    url = models.URLField()
+    criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating")
 
+    def __str__(self):
+        return self.name
+
+    def rate(self, criterion, rating):
+        """Defines how much (rating) the sport meets the given criterion"""
+        rating_obj, _ = CriterionRating.objects.get_or_create(
+            sport=self, criterion=criterion, defaults={"rating": rating}
+        )
+        rating_obj.rating = rating
+        rating_obj.save()
+        return rating_obj
+
+    def get_rating(self, criterion):
+        """Returns how much the sport meets the given criterion"""
+        criterion_rating = CriterionRating.objects.get(sport=self, criterion=criterion)
+        return criterion_rating.rating
+
+
+class Criterion(models.Model):
+    """
+    Defines a Sport property that is used a a criterion for our quiz.
+    (e.g. Individual or Team sport)
+    """
+
+    name = models.TextField()
diff --git a/unisportomat/quiz/tests.py b/unisportomat/quiz/tests.py
index 7ce503c2dd97ba78597f6ff6e4393132753573f6..3c8a3f087dfcd217ae3297e625c2355ec692c3b7 100644
--- a/unisportomat/quiz/tests.py
+++ b/unisportomat/quiz/tests.py
@@ -1,3 +1,76 @@
+""" This module tests all our quiz models"""
+
 from django.test import TestCase
+from .models import Sport, Criterion
+
+
+class SportModelTest(TestCase):
+    """Tests the sport model"""
+
+    def setUp(self):
+        self.name = "HIIT"
+        self.url = (
+            "https://www.buchsys.de/fu-berlin/angebote/aktueller_zeitraum/_HIIT_"
+            "-_High_Intensity_Interval_Training___HOME.html "
+        )
+
+        self.test_sport = Sport(
+            name=self.name,
+            url=self.url,
+        )
+
+        self.test_sport.save()
+
+    def test_sport_can_be_created(self):
+        """New sport is written to the database"""
+        test_sport = Sport.objects.first()
+        self.assertEqual(test_sport.name, self.name)
+        self.assertEqual(test_sport.url, self.url)
+
+
+class CriterionRatingTest(TestCase):
+    """Tests the Relation between Sport and Criterion"""
+
+    def setUp(self):
+        self.name = "HIIT"
+        self.url = (
+            "https://www.buchsys.de/fu-berlin/angebote/aktueller_zeitraum/_HIIT_"
+            "-_High_Intensity_Interval_Training___HOME.html "
+        )
+
+        self.test_sport = Sport(
+            name=self.name,
+            url=self.url,
+        )
+
+        self.test_sport.save()
+
+        self.criterion = Criterion(name="Einzelsport")
+        self.criterion.save()
+
+    def test_can_rate_criterion_for_sport(self):
+        """A rating for a specific criterion can be added to a sport"""
+        self.test_sport.rate(self.criterion, 10)
+        self.assertEqual(self.test_sport.criteria_ratings.first(), self.criterion)
+        self.assertEqual(self.test_sport.get_rating(self.criterion), 10)
+
+    def test_rating_can_be_changed(self):
+        """
+        If a sport is rated again then the corresponding relation is changed,
+        instead of recreated
+        """
+        first_rating_object = self.test_sport.rate(self.criterion, 10)
+        second_rating_object = self.test_sport.rate(self.criterion, 8)
+        self.assertEqual(first_rating_object, second_rating_object)
+        self.assertEqual(self.test_sport.get_rating(criterion=self.criterion), 8)
+
+
+class CriterionModelTest(TestCase):
+    """Tests the Criterion model"""
 
-# Create your tests here.
+    def test_criterion_can_be_created(self):
+        """New criterion is saved to the db"""
+        name = "Einzelsport"
+        Criterion(name=name).save()
+        test_criterion = Criterion.objects.first()
+        self.assertEqual(test_criterion.name, name)
diff --git a/unisportomat/unisportomat/settings.py b/unisportomat/unisportomat/settings.py
index 511778922d9ff448581c1ea06294dbd7f530f096..23f0cbdb1ed78fc8b2dfd21a2e5c4e27ac3eca39 100644
--- a/unisportomat/unisportomat/settings.py
+++ b/unisportomat/unisportomat/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
 # Application definition
 
 INSTALLED_APPS = [
+    'quiz.apps.QuizConfig',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',