diff --git a/README.md b/README.md
index 3a7ebde118a0af117312b2551b2dd70773945108..f12cbfe67d78014523c35c8d1c1059034aa2ee17 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,6 @@
 
 [![Demo](https://img.shields.io/badge/demo-dashboards-blue)](http://real-astron.nl/grafana)
 
-TODO:
-
-* Fix django app (main URL 404s)
-* (fixed) Metrics not exported to prometheus
-* Provision dashboard found at https://grafana.com/grafana/dashboards/9528-django-prometheus/
-* Make all metrics work in dashboard
-
 ## Welcome
 Welcome to the Grafana Deploy! This repository lets you set up your grafana
 instance in a few seconds. 
diff --git a/django/mysite/mysite/settings.py b/django/mysite/mysite/settings.py
index 176b1c7a46601e9f41f704bba285560da63b1f73..aab0f653a1c6894d1173592790efdc160d444c5f 100644
--- a/django/mysite/mysite/settings.py
+++ b/django/mysite/mysite/settings.py
@@ -31,6 +31,8 @@ ALLOWED_HOSTS = ["*"]
 # Application definition
 
 INSTALLED_APPS = [
+    "polls.apps.PollsConfig",
+
     "django.contrib.admin",
     "django.contrib.auth",
     "django.contrib.contenttypes",
@@ -38,6 +40,8 @@ INSTALLED_APPS = [
     "django.contrib.messages",
     "django.contrib.staticfiles",
 
+    "rest_framework",
+
     "django_prometheus",
 ]
 
@@ -127,3 +131,11 @@ STATIC_URL = "static/"
 # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
 
 DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+
+# DRF
+
+REST_FRAMEWORK = {
+    'DEFAULT_PERMISSION_CLASSES': [
+        'rest_framework.permissions.AllowAny'
+    ]
+}
diff --git a/django/mysite/mysite/urls.py b/django/mysite/mysite/urls.py
index 2759024b47a08d2f8c2fe680aa559dfe1fa41b99..f39aee99eb98d10e0d16de47003ca7374e72b782 100644
--- a/django/mysite/mysite/urls.py
+++ b/django/mysite/mysite/urls.py
@@ -16,9 +16,14 @@ Including another URLconf
 """
 from django.contrib import admin
 from django.urls import path, include
+from django.contrib.auth.models import User
 
 urlpatterns = [
     path("admin/", admin.site.urls),
 
+    path("polls/", include("polls.urls")),
+
+    path('api-auth/', include('rest_framework.urls')),
+
     path('', include('django_prometheus.urls')),
 ]
diff --git a/django/mysite/polls/__init__.py b/django/mysite/polls/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/django/mysite/polls/admin.py b/django/mysite/polls/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c38f3f3dad51e4585f3984282c2a4bec5349c1e
--- /dev/null
+++ b/django/mysite/polls/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/django/mysite/polls/apps.py b/django/mysite/polls/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..5184937ac15ec9a1b97df004f9853525da5fac6d
--- /dev/null
+++ b/django/mysite/polls/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class PollsConfig(AppConfig):
+    default_auto_field = "django.db.models.BigAutoField"
+    name = "polls"
diff --git a/django/mysite/polls/migrations/__init__.py b/django/mysite/polls/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/django/mysite/polls/models.py b/django/mysite/polls/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..c88accd60cc24a5bdc213563e819cef34bfba6fc
--- /dev/null
+++ b/django/mysite/polls/models.py
@@ -0,0 +1,13 @@
+from django.db import models
+from django_prometheus.models import ExportModelOperationsMixin
+
+
+class Question(ExportModelOperationsMixin('question'), models.Model):
+    question_text = models.CharField(max_length=200)
+    pub_date = models.DateTimeField("date published")
+
+
+class Choice(ExportModelOperationsMixin('choice'), models.Model):
+    question = models.ForeignKey(Question, on_delete=models.CASCADE)
+    choice_text = models.CharField(max_length=200)
+    votes = models.IntegerField(default=0)
diff --git a/django/mysite/polls/tests.py b/django/mysite/polls/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/django/mysite/polls/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/django/mysite/polls/urls.py b/django/mysite/polls/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..3357f02dd69ad6d6a8274929cdce20f1d6139801
--- /dev/null
+++ b/django/mysite/polls/urls.py
@@ -0,0 +1,14 @@
+from django.urls import path, include
+
+from . import views
+
+from rest_framework import routers
+
+# Routers provide an easy way of automatically determining the URL conf.
+router = routers.DefaultRouter()
+router.register(r'question', views.QuestionViewSet)
+router.register(r'choice', views.ChoiceViewSet)
+
+urlpatterns = [
+    path('', include(router.urls)),
+]
diff --git a/django/mysite/polls/views.py b/django/mysite/polls/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..56fe19d64f8250d782bf4af1f4eec5de6f3de12c
--- /dev/null
+++ b/django/mysite/polls/views.py
@@ -0,0 +1,23 @@
+from django.http import HttpResponse
+from rest_framework import serializers, viewsets
+from .models import Question, Choice
+
+# Serializers define the API representation.
+class QuestionSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = Question
+        fields = '__all__'
+
+class ChoiceSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = Choice
+        fields = '__all__'
+
+# ViewSets define the view behavior.
+class QuestionViewSet(viewsets.ModelViewSet):
+    queryset = Question.objects.all()
+    serializer_class = QuestionSerializer
+
+class ChoiceViewSet(viewsets.ModelViewSet):
+    queryset = Choice.objects.all()
+    serializer_class = ChoiceSerializer
diff --git a/django/requirements.txt b/django/requirements.txt
index 5a4563ac0c360cbab1686af44eecebbb3b517239..108cd6de5b572f19cd13bd868ca246860f51cf0c 100644
--- a/django/requirements.txt
+++ b/django/requirements.txt
@@ -1,4 +1,11 @@
+# Django
 django
 tzdata
 
+# DRF
+djangorestframework
+markdown
+django-filter
+
+# Metrics
 django-prometheus
diff --git a/docker-compose.yml b/docker-compose.yml
index f0ec36d57e4500c3e982ae5740db27826c58948b..391302c55073febea7e3de70d05508cf27b49136 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -69,11 +69,11 @@ services:
     container_name: django
     ports:
       - "8000:8000"
-    entrypoint:
-      - python3
-      - /src/mysite/manage.py
-      - runserver
-      - 0.0.0.0:8000
+    working_dir: /src/mysite
+    command: >
+      sh -c "python3 manage.py makemigrations
+             python3 manage.py migrate
+             python3 manage.py runserver 0.0.0.0:8000"
     networks:
       - monitoring