diff --git a/.pylintrc b/.pylintrc
index a38492d526b184470b00af41da106143c0122e1e..0deca7bc1ce42b9f694aaa973329a5d344013766 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -3,4 +3,9 @@ fail-under=10
 
 [MESSAGES CONTROL]
 disable=line-too-long,
-        django-not-configured
+        django-not-configured,
+        too-few-public-methods,
+        no-self-use,
+        abstract-method,
+        arguments-differ,
+        invalid-name
diff --git a/README.md b/README.md
index fa9b5435047925eda043a98975c7f10b4283980b..075146a4cb0ac01f5e58a25ff1f64718db803781 100644
--- a/README.md
+++ b/README.md
@@ -113,4 +113,25 @@ activate(cur_language) # Resets active language to the one before manual activat
 
 ```
 
-This might be particularly useful for entering data from the Admin Frontend into the database, or choosing the language for the User Frontend if the Browser Locale cannot be used.
\ No newline at end of file
+This might be particularly useful for entering data from the Admin Frontend into the database, or choosing the language for the User Frontend if the Browser Locale cannot be used.
+
+
+## Pagination in Views
+
+Every list that needs to be paginated needs a paginator.
+Here, the Paginator object is created in the GET call.
+The Queryset which is supposed to be paginated needs to be run through the function:
+
+```python
+new_queryset = paginator.paginate_queryset(complete_queryset, request)
+```
+
+The new_queryset is a List, not a Manager, so it can be directly iterated upon.
+After the data has been worked on and run through the Serializer as normal,
+instead of returning Result(data), the paginator needs to be used again so it can add its page metadata:
+
+```python
+return paginator.get_paginated_response(serializer.data)
+```
+
+This function already returns a fully valid Response, so it can be directly returned.
\ No newline at end of file
diff --git a/unisportomat/quiz/fixtures/criteria.json b/unisportomat/quiz/fixtures/criteria.json
index 584ded6433489d92a803179cea13f8313434e63b..597ae13c3cd90f3df8ae5c05215809a2b0013d29 100644
--- a/unisportomat/quiz/fixtures/criteria.json
+++ b/unisportomat/quiz/fixtures/criteria.json
@@ -2,6 +2,7 @@
   {
     "model": "quiz.criterion",
     "pk": 1,
+    "question": 1,
     "fields": {
       "name": "Outdoorsport"
     }
diff --git a/unisportomat/quiz/management/commands/seed_db.py b/unisportomat/quiz/management/commands/seed_db.py
index ded2a9140dbf7a9ca8de92726f4476b3dcde1434..d6a6d836735a50158d0857d57278b5e41df1dc1c 100644
--- a/unisportomat/quiz/management/commands/seed_db.py
+++ b/unisportomat/quiz/management/commands/seed_db.py
@@ -74,7 +74,7 @@ class Command(BaseCommand):
             "Bouldern",
         ]
         for name in sports_names:
-            Sport(name=name).save()
+            Sport.objects.create_sport(name=name).save()
 
         # Create criteria
         criteria_names = [
@@ -85,7 +85,7 @@ class Command(BaseCommand):
             "Kampfsport",
         ]
         for name in criteria_names:
-            Criterion(name=name).save()
+            Criterion.objects.create_criterion(name=name).save()
 
         # Create ratings for all sports and criterions
         for sport in Sport.objects.all():
diff --git a/unisportomat/quiz/models.py b/unisportomat/quiz/models.py
index d582994f73b3de31d04f59e1a1e8d16539cf3ed8..9a7b5b18510fdc173a512afbf3959659ca51319b 100644
--- a/unisportomat/quiz/models.py
+++ b/unisportomat/quiz/models.py
@@ -1,9 +1,19 @@
 """ Model definitions for the quiz """
 
-from django.core.validators import MaxValueValidator, MinValueValidator
+from django.core.exceptions import ValidationError
 from django.db import models
 
 
+def validate_rating(value):
+    """
+    This function acts as a validator for ratings.
+    Sadly, it isn't called automatically, so it needs to be used manually.
+    """
+
+    if not ((10 >= value >= 1) or value == -1):
+        raise ValidationError(u"%s is not a valid rating!" % value)
+
+
 class CriterionRating(models.Model):
     """
     This is the relation between Sport and Criterion.
@@ -11,9 +21,7 @@ class CriterionRating(models.Model):
     To see it's usage check Sport.rate() and Sport.get_rating()
     """
 
-    rating = models.IntegerField(
-        validators=[MaxValueValidator(10), MinValueValidator(1)]
-    )
+    rating = models.IntegerField(validators=[validate_rating])
     criterion = models.ForeignKey("Criterion", on_delete=models.CASCADE)
     sport = models.ForeignKey("Sport", on_delete=models.CASCADE)
 
@@ -21,6 +29,28 @@ class CriterionRating(models.Model):
         return str(self.sport) + " - " + str(self.criterion) + ": " + str(self.rating)
 
 
+class SportManager(models.Manager):
+    """
+    Manages Creation of Sport Objects
+    Since every Criterion Connection needs to be present in the DB at all times,
+    the connections are made at creation of the Sport object. For this, Sport objects need to be
+    created through this Manager Class.
+
+    Docs: https://docs.djangoproject.com/en/3.2/ref/models/instances/#creating-objects
+    """
+
+    def create_sport(self, **kwargs):
+        """
+        Creates new Sport Object and every CriterionRating for it
+        """
+        sport = self.create(**kwargs)
+
+        for crit in Criterion.objects.iterator():
+            sport.rate(crit, -1)
+
+        return sport
+
+
 class Sport(models.Model):
     """
     Defines a Sport with name, url that leads to the booking page.
@@ -32,6 +62,8 @@ class Sport(models.Model):
     url = models.URLField()
     criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating")
 
+    objects = SportManager()
+
     def __str__(self):
         return self.name
 
@@ -40,6 +72,7 @@ class Sport(models.Model):
         rating_obj, _ = CriterionRating.objects.get_or_create(
             sport=self, criterion=criterion, defaults={"rating": rating}
         )
+        validate_rating(rating)
         rating_obj.rating = rating
         rating_obj.save()
         return rating_obj
@@ -49,6 +82,42 @@ class Sport(models.Model):
         criterion_rating = CriterionRating.objects.get(sport=self, criterion=criterion)
         return criterion_rating.rating
 
+    def is_filled(self):
+        """
+        Returns a Boolean whether all Criterions are given a valid rating (unequal to -1)
+        """
+
+        for crit in self.criteria_ratings.iterator():
+            if self.get_rating(crit) == -1:
+                return False
+
+        return True
+
+
+class CriterionManager(models.Manager):
+    """
+    Manages Creation of Criterion Objects
+    Since every Sport Object needs to be rated in every Criterion,
+    when a new Criterion is created, every Sport object needs to be rated for that Criterion.
+    As a default value, -1 is entered so that it can be recognized that no true value is given.
+
+    Docs: https://docs.djangoproject.com/en/3.2/ref/models/instances/#creating-objects
+    """
+
+    def create_criterion(self, **kwargs):
+        """
+        Creates a Criterion Object and Rates every existing Sport with -1
+        """
+        crit = Criterion(**kwargs)
+
+        # Criterion needs to be saved before it can be connected to a sport
+        crit.save()
+
+        for sport in Sport.objects.iterator():
+            sport.rate(crit, -1)
+
+        return crit
+
 
 class Criterion(models.Model):
     """
@@ -58,9 +127,27 @@ class Criterion(models.Model):
 
     name = models.TextField()
 
+    objects = CriterionManager()
+
     def __str__(self):
         return self.name
 
+    def get_active_sum(self):
+        """
+        Get Number of Sports with Rating larger than 1 and the cumulated sum of all ratings
+        TODO: Think about Usefulness of Rating Sums with 1 as Min Value
+        """
+
+        num_active = 0
+        rating_sum = 0
+
+        for rating_obj in CriterionRating.objects.filter(criterion=self):
+            rating_sum += rating_obj.rating
+            if rating_obj.rating > 1:
+                num_active += 1
+
+        return num_active, rating_sum
+
 
 class CallToMove(models.Model):
     """Defines text and image that are used to show a call to move between questions"""
diff --git a/unisportomat/quiz/serializers.py b/unisportomat/quiz/serializers.py
index 584e145715661a9ab7d5ac7a2406e0d6b9463475..9756a8e190171e12071bfbd365b05c6dc05813f3 100644
--- a/unisportomat/quiz/serializers.py
+++ b/unisportomat/quiz/serializers.py
@@ -2,7 +2,7 @@
 Serializers creating JSONs for every Model from .models
 """
 from rest_framework import serializers
-from .models import Sport, Criterion, Question
+from .models import Sport, Criterion, Question, validate_rating
 
 
 class SportListSerializer(serializers.ModelSerializer):
@@ -22,7 +22,6 @@ class QuestionListSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Question
-
         fields = ("id", "text", "criterion")
 
 
@@ -34,3 +33,169 @@ class CriterionListSerializer(serializers.ModelSerializer):
     class Meta:
         model = Criterion
         fields = ("id", "name")
+
+
+class SmallSportListSerializer(serializers.BaseSerializer):
+    """
+    Serializes Lists of Sport Objects in a "Simple" Manner, with Criterions being represented in a Bool.
+    """
+
+    def to_representation(self, sport_filled_tuples):
+        """
+        Takes a List of (Sport, bool) tuples to Serialize.
+        The Bool Represents whether the Sport is Filled or not.
+        """
+
+        serialized_data = []
+
+        for sport, boolean in sport_filled_tuples:
+            serialized_data.append(
+                {
+                    "id": sport.pk,
+                    "name": sport.name,
+                    "url": sport.url,
+                    "is_filled": boolean,
+                }
+            )
+
+        return serialized_data
+
+
+class SingleSportSerializer(serializers.BaseSerializer):
+    """
+    Serializes and Deserializes a Single Sport Object
+    """
+
+    def to_representation(self, sport):
+        """
+        Takes a Single Sport Object and Serializes it and all its Criteria
+        """
+
+        serialized_data = {}
+
+        serialized_data["id"] = sport.pk
+        serialized_data["name"] = sport.name
+        serialized_data["url"] = sport.url
+
+        criteria = []
+
+        for criterion in sport.criteria_ratings.iterator():
+            criterion_data = {}
+
+            criterion_data["id"] = criterion.pk
+            criterion_data["name"] = criterion.name
+
+            criterion_data["value"] = sport.get_rating(criterion)
+
+            criteria.append(criterion_data)
+
+        serialized_data["criteria"] = criteria
+
+        return serialized_data
+
+    def to_internal_value(self, request):
+        """
+        The Data in the Request is taken and written to another Dictionary.
+        During this process, the Data is Validated on whether the Rating Value and Criterion ID are valid.
+        If the Request is PATCHing or PUTting an existing Sport, not every field must be existant.
+        So, the existance is explicitly checked.
+        TODO: Different Functions based on PUT or PATCH?
+        """
+
+        sport_dictionary = {}
+
+        # If The Sport is Being Patched, Name or URL may not be changed.
+        # That means that those Fields might not be sent in the Request,
+        # leading to needing to check whether they exist.
+        if "name" in request.data.keys():
+            sport_dictionary["name"] = request.data["name"]
+
+        if "url" in request.data.keys():
+            sport_dictionary["url"] = request.data["url"]
+
+        # If the Sport is only now created with a POST-Request, no Criteria can be filled out for it
+        # This is because the Admin Frontend doesn't have a list of Criteria ready
+        if "criteria" in request.data.keys():
+
+            # A Number of Criteria may be sent with the Sport
+            sport_dictionary["criteria"] = []
+
+            # For every Sent Criterion, the ID of the Criterion and the Rating Value is being tested for Validity
+            for criterion in request.data["criteria"]:
+
+                value = criterion["value"]
+                try:
+                    validate_rating(value)
+                    crit = Criterion.objects.get(pk=criterion["id"])
+                except:  # pylint: disable=bare-except
+                    return None
+
+                sport_dictionary["criteria"].append((crit, value))
+
+        return sport_dictionary
+
+
+class IncompleteSportSerializer(serializers.BaseSerializer):
+    """
+    Serializes every Sport Object with Incomplete Criteria Ratings.
+    Includes the Name and ID of both the Sport and the Criteria.
+    """
+
+    def to_representation(self, incomplete_sports):
+        """
+        Serializes Every given Sport Object and goes through every Criterium to serialize those that are unrated.
+        """
+
+        incomplete_sport_list = []
+
+        for sport in incomplete_sports:
+            incomplete_sport = {
+                "id": sport.pk,
+                "name": sport.name,
+                "criteria": [],
+            }
+
+            for crit in sport.criteria_ratings.iterator():
+                # Asking this way to save an indentation and for readability. Would also work when asking for = -1 and handling the append then.
+                if sport.get_rating(crit) != -1:
+                    continue
+
+                incomplete_sport["criteria"].append(
+                    {
+                        "id": crit.pk,
+                        "name": crit.name,
+                    }
+                )
+
+            incomplete_sport_list.append(incomplete_sport)
+
+        return incomplete_sport_list
+
+
+class CriteriaSerializer(serializers.BaseSerializer):
+    """
+    Serializes Every Criterium and Metadata
+    """
+
+    def to_representation(self, data):
+        """
+        Takes Tuples of (Criterium, Int, Int),
+        where the Integers are the Number of Sports in which the Rating is >1
+        and the cumulated sum of Ratings >1, respectively
+        """
+
+        criteria_list = []
+
+        for crit, active_sports, sum_of_weights in data:
+
+            criterion_dict = {}
+
+            criterion_dict["id"] = crit.pk
+            criterion_dict["question_id"] = crit.question.pk
+            criterion_dict["name"] = crit.name
+            criterion_dict["number_of_sports_active"] = active_sports
+            criterion_dict["sum_of_weights"] = sum_of_weights
+
+            criteria_list.append(criterion_dict)
+
+        return criteria_list
diff --git a/unisportomat/quiz/tests.py b/unisportomat/quiz/tests.py
index 542d2c5e8cfdd224a2307e24509f1a9717e94410..80149025adbcb2b810b96ea4226dc47158511346 100644
--- a/unisportomat/quiz/tests.py
+++ b/unisportomat/quiz/tests.py
@@ -7,7 +7,9 @@ import tempfile
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.core.management import call_command
 from django.utils.translation import get_language, activate
+from django.urls import reverse
 from django.test import TestCase, override_settings
+from rest_framework.test import APITestCase
 from django.conf import settings
 from .models import (
     Sport,
@@ -379,3 +381,142 @@ class Modeltranslation_Two_Languages_Test(TestCase):
 
         self.assertEqual(self.question.text, self.question.text_en)
         self.assertNotEqual(self.question.text, self.question.text_de)
+
+
+class APITest(APITestCase):
+    """Tests the Django API"""
+
+    fixtures = [
+        "sports.json",
+        "criteria.json",
+        "criterion_ratings.json",
+        "questions.json",
+    ]
+
+    def test_get_sport_returns_correct_data(self):
+        """Test the API endpoint /sport/{id}"""
+        response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1}))
+        sport_data = {
+            "id": 1,
+            "name": "Jiu Jitsu",
+            "url": "http://www.test.de",
+            "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}],
+        }
+        self.assertDictEqual(response.data, sport_data)
+
+    def test_put_sport_makes_correct_changes(self):
+        """
+        Test the API endpoint /sport/{id} for put requests
+        """
+        sport_data = {
+            "name": "Karate",
+            "url": "http://www.test2.de",
+            "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}],
+        }
+
+        response = self.client.put(
+            reverse("small-sport-list-detail", kwargs={"pk": 1}),
+            data=sport_data,
+            format="json",
+        )
+        self.assertEqual(response.data["name"], sport_data["name"])
+        self.assertEqual(response.data["url"], sport_data["url"])
+        self.assertEqual(len(response.data["criteria"]), Criterion.objects.count())
+        self.assertDictEqual(
+            response.data["criteria"][0], {"id": 1, "name": "Outdoorsport", "value": 1}
+        )
+
+    def test_patch_sport_makes_correct_changes(self):
+        """
+        Test the API endpoint /sport/{id} for patch requests
+        """
+        sport_data = {
+            "criteria": [{"id": 1, "value": 3}],
+        }
+
+        response = self.client.patch(
+            reverse("small-sport-list-detail", kwargs={"pk": 1}),
+            data=sport_data,
+            format="json",
+        )
+        self.assertEqual(response.data["name"], "Jiu Jitsu")
+        self.assertEqual(response.data["url"], "http://www.test.de")
+        self.assertEqual(len(response.data["criteria"]), Criterion.objects.count())
+        self.assertDictEqual(
+            response.data["criteria"][0], {"id": 1, "name": "Outdoorsport", "value": 3}
+        )
+
+    def test_get_sports_returns_correct_data(self):
+        """Test if API endpoint /sport returns correct sports list"""
+
+        response = self.client.get(reverse("small-sport-list-list"))
+
+        sport_data = [
+            {
+                "id": 1,
+                "is_filled": True,
+                "name": "Jiu Jitsu",
+                "url": "http://www.test.de",
+            }
+        ]
+        self.assertListEqual(response.data["results"], sport_data)
+        self.assertEqual(response.data["count"], 1)
+
+    def test_post_sports_creates_correct_entry(self):
+        """Test if post to /sport creates a correct object"""
+        sport_data_new = {
+            "name": "Karate",
+            "url": "http://www.test2.de",
+        }
+
+        response = self.client.post(
+            reverse("small-sport-list-list"), data=sport_data_new
+        )
+        self.assertEqual(response.data["name"], sport_data_new["name"])
+        self.assertEqual(response.data["url"], sport_data_new["url"])
+        self.assertEqual(len(response.data["criteria"]), Criterion.objects.count())
+        self.assertEqual(Sport.objects.count(), 2)
+
+    def test_delete_sports_creates_correct_entry(self):
+        """Test if delete to /sports deletes an object"""
+
+        response = self.client.delete(
+            reverse("small-sport-list-detail", kwargs={"pk": 1})
+        )
+
+        self.assertEqual(Sport.objects.count(), 0)
+
+    def test_get_incomplete_sport_list(self):
+        """
+        Tests if get to /sport/incomplete/ returns a list of incomplete sports
+        """
+
+        # Set Up Incomplete Sport
+        response = self.client.patch(
+            reverse("small-sport-list-detail", kwargs={"pk": 1}),
+            data={"criteria": [{"id": 1, "value": -1}]},
+            format="json",
+        )
+
+        response = self.client.get(reverse("incomplete"))
+
+        self.assertEqual(len(response.data["results"]), 1)
+        self.assertEqual(response.data["results"][0]["name"], "Jiu Jitsu")
+
+    def test_get_criteria(self):
+        """
+        Tests if get /critera/ returns a list of all criteria
+        """
+
+        # Set Up Values
+        response = self.client.patch(
+            reverse("small-sport-list-detail", kwargs={"pk": 1}),
+            data={"criteria": [{"id": 1, "value": 7}]},
+            format="json",
+        )
+
+        response = self.client.get(reverse("criteria"))
+
+        self.assertEqual(len(response.data), Criterion.objects.count())
+        self.assertEqual(response.data[0]["number_of_sports_active"], 1)
+        self.assertEqual(response.data[0]["sum_of_weights"], 7)
diff --git a/unisportomat/quiz/views.py b/unisportomat/quiz/views.py
index 03cb6f920dc1ad9f4aed1e338c7c4333dd736927..8d7e0cf870f1e7abe163f32f9f1b45b1dde0a76a 100644
--- a/unisportomat/quiz/views.py
+++ b/unisportomat/quiz/views.py
@@ -4,10 +4,20 @@ Defines the views for the API
 
 # from django.shortcuts import render
 from rest_framework import viewsets
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from django.shortcuts import get_object_or_404
+from django.http import HttpResponse
+from .pagination import PageNumberWithPageSizePagination
+
 from .serializers import (
+    SmallSportListSerializer,
     SportListSerializer,
     CriterionListSerializer,
     QuestionListSerializer,
+    SingleSportSerializer,
+    CriteriaSerializer,
+    IncompleteSportSerializer,
 )
 from .models import Sport, Criterion, Question
 
@@ -39,3 +49,214 @@ class QuestionListView(viewsets.ModelViewSet):  # pylint: disable=too-many-ances
 
     serializer_class = QuestionListSerializer
     queryset = Question.objects.all()
+
+
+# Dev Notes:
+# - If we want to include a View in the Router in urls.py, the View needs to be a Viewset
+# - Those are mostly meant for Lists of Objects, so instead of get() and post(), list() and create() are used respectively
+# https://stackoverflow.com/questions/30389248/how-can-i-register-a-single-view-not-a-viewset-on-my-router
+
+
+class SmallSportListView(viewsets.ViewSet):
+    """
+    View for Sports and List of Sport:
+    List returns every Sport with the is_filled Field
+    Detail returns single Sports with every Criterium
+    """
+
+    authentication_classes = []
+
+    # GET for api/admin/sport/
+    def list(self, request):
+        """
+        GET for api/admin/sport/
+        Returns a List of Every Sport with the is_filled Field, stating whether every Criterion is given a Rating or not
+        """
+
+        paginator = PageNumberWithPageSizePagination()
+
+        sports = Sport.objects.all().order_by("name")
+        sports = paginator.paginate_queryset(sports, request)
+        is_filled_tuples = []
+
+        for sport in sports:
+
+            is_filled_tuples.append((sport, sport.is_filled()))
+
+        serializer = SmallSportListSerializer(is_filled_tuples)
+
+        return paginator.get_paginated_response(serializer.data)
+
+    # POST for api/admin/sport/
+    def create(self, request):
+        """
+        POST for api/admin/sport/
+        View for Creating a New Sport
+        """
+
+        request_data = SingleSportSerializer().to_internal_value(request)
+
+        # A Try at Error Catching
+        if request_data is None:
+            return HttpResponse(status=400)
+
+        new_sport = Sport.objects.create_sport()
+
+        new_sport.name = request_data["name"]
+        new_sport.url = request_data["url"]
+
+        new_sport.save()
+
+        response = SingleSportSerializer(new_sport)
+
+        return Response(response.data)
+
+    # GET for api/admin/sport/<id>/
+    def retrieve(self, request, pk=None):
+        """
+        GET for api/admin/sport/<pk>/
+        View for getting a Single Sport, with the pk to the Sport being the argument in the URL
+        """
+
+        sport = get_object_or_404(Sport, pk=pk)
+
+        response = SingleSportSerializer(sport)
+
+        return Response(response.data)
+
+    # PUT for api/admin/sport/<id>/
+    def update(self, request, pk=None):
+        """
+        PUT for api/admin/sport/<id>/
+        Creates a Sport if it doesn't exist, otherwise overwrites it.
+        TODO: Maybe Rework PUT if needed of Admin Frontend
+        """
+
+        # Get Data from Serializer
+        request_data = SingleSportSerializer().to_internal_value(request)
+
+        if request_data is None:
+            # Something is Broke, so Refuse Changing Data
+            return HttpResponse(status=400)
+
+        # Get Sport from Data
+        sport = Sport.objects.get(pk=pk)
+
+        # Apply New Data to Sport
+        sport.name = request_data["name"]
+        sport.url = request_data["url"]
+
+        # Overwrite Criterion Ratings
+        for criterion, value in request_data["criteria"]:
+            sport.rate(criterion, value)
+
+        # Re-Serialize changed Sport and Send it back
+        response = SingleSportSerializer(sport)
+
+        return Response(response.data)
+
+    # PATCH for api/admin/sport/<id>/
+    def partial_update(self, request, pk=None):
+        """
+        PATCH for api/admin/sport/<id>/
+        Fills in the given Values into the Sport specified in the URL
+        """
+
+        # Get Data from Serializer
+        request_data = SingleSportSerializer().to_internal_value(request)
+
+        if request_data is None:
+            # Something is Broke, so Refuse Changing Data
+            return HttpResponse(status=400)
+
+        # Get Sport from Data
+        sport = Sport.objects.get(pk=pk)
+
+        # Apply New Data to Sport, if it exists
+        if "name" in request_data.keys():
+            sport.name = request_data["name"]
+
+        if "url" in request_data.keys():
+            sport.url = request_data["url"]
+
+        # Overwrite Criterion Ratings
+        for criterion, value in request_data["criteria"]:
+            sport.rate(criterion, value)
+
+        # Re-Serialize changed Sport and Send it back
+        response = SingleSportSerializer(sport)
+
+        return Response(response.data)
+
+    # DELETE for api/admin/sport/<id>/
+    def destroy(self, request, pk=None):
+        """
+        DELETE for api/admin/sport/<id>/
+        Removes Sport Object specified in the URL
+        """
+
+        sport = get_object_or_404(Sport, pk=pk)
+
+        sport.delete()
+
+        return HttpResponse(status=404)
+
+
+class IncompleteSportView(APIView):
+    """
+    Returns all Sport Objects with Incomplete Ratings
+    """
+
+    authentication_classes = []
+
+    # GET for api/admin/sport/incomplete/
+    def get(self, request):
+        """
+        GET for api/admin/sport/incomplete/
+        Returns every incomplete Sport with its incomplete Ratings in a paginated manner
+        """
+
+        paginator = PageNumberWithPageSizePagination()
+        queryset = Sport.objects.all().order_by("name")
+        queryset = paginator.paginate_queryset(queryset, request)
+
+        incomplete_sport_list = []
+
+        for sport in queryset:
+
+            if not sport.is_filled():
+                incomplete_sport_list.append(sport)
+
+        response = IncompleteSportSerializer(incomplete_sport_list)
+
+        return paginator.get_paginated_response(response.data)
+
+
+class CriteriaView(APIView):
+    """
+    View for the List of Criteria and their Metadata
+    """
+
+    authentication_classes = []
+
+    # GET for api/admin/criteria/
+    def get(self, request):
+        """
+        GET for api/admin/criteria/
+        Returns every Criterium and the Metadata of
+        Number of Sports in which the Rating is >1
+        and the cumulated sum of Ratings >1
+        TODO: Also Pagination
+        """
+
+        data = []
+
+        for crit in Criterion.objects.iterator():
+
+            active_sports, sum_of_weights = crit.get_active_sum()
+
+            data.append((crit, active_sports, sum_of_weights))
+
+        response = CriteriaSerializer(data)
+
+        return Response(response.data)
diff --git a/unisportomat/unisportomat/urls.py b/unisportomat/unisportomat/urls.py
index 801097cd6baa927bd468c4b170c198230b30dfe9..388d94e57dc1440659c8320eca2485f5bd78fee9 100644
--- a/unisportomat/unisportomat/urls.py
+++ b/unisportomat/unisportomat/urls.py
@@ -22,8 +22,15 @@ router = routers.DefaultRouter()
 router.register(r"sport-list", views.SportListView, "sport-list")
 router.register(r"criterion-list", views.CriterionListView, "criterion-list")
 router.register(r"question-list", views.QuestionListView, "question-list")
+router.register(r"small-sport-list", views.SmallSportListView, "small-sport-list")
 
 urlpatterns = [
     path("admin/", admin.site.urls),
     path("api/admin/", include(router.urls)),
+    path(
+        "api/admin/sport/incomplete/",
+        views.IncompleteSportView.as_view(),
+        name="incomplete",
+    ),
+    path("api/admin/criteria/", views.CriteriaView.as_view(), name="criteria"),
 ]