diff --git a/django/website/tabbed_page/admin.py b/django/website/tabbed_page/admin.py
index 7c897219268b2aa8bf4dc8056844feb01b25fc73..050fc71c4404a8bcb373dba57671b31bd97da86a 100644
--- a/django/website/tabbed_page/admin.py
+++ b/django/website/tabbed_page/admin.py
@@ -1,9 +1,9 @@
 from django.contrib import admin
-from .models import TabbedPage, Tab
+from .models import TabbedPage, TabInstance
 
 
 class TabInline(admin.StackedInline):
-    model = Tab
+    model = TabInstance
     extra = 0
 
 
diff --git a/django/website/tabbed_page/migrations/0002_auto_20150805_1521.py b/django/website/tabbed_page/migrations/0002_auto_20150805_1521.py
new file mode 100644
index 0000000000000000000000000000000000000000..c0ed816adbf051c33cb3dc0327a3bf6adadefecc
--- /dev/null
+++ b/django/website/tabbed_page/migrations/0002_auto_20150805_1521.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import jsonfield.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tabbed_page', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='TabInstance',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('settings', jsonfield.fields.JSONField(blank=True)),
+                ('view_name', models.CharField(max_length=128)),
+                ('name', models.CharField(max_length=128)),
+                ('default', models.BooleanField(default=False)),
+                ('position', models.PositiveIntegerField(default=0)),
+                ('label', models.CharField(max_length=128)),
+                ('page', models.ForeignKey(to='tabbed_page.TabbedPage')),
+            ],
+        ),
+        migrations.AlterUniqueTogether(
+            name='tab',
+            unique_together=set([]),
+        ),
+        migrations.RemoveField(
+            model_name='tab',
+            name='page',
+        ),
+        migrations.DeleteModel(
+            name='Tab',
+        ),
+        migrations.AlterUniqueTogether(
+            name='tabinstance',
+            unique_together=set([('name', 'page')]),
+        ),
+    ]
diff --git a/django/website/tabbed_page/models.py b/django/website/tabbed_page/models.py
index a5f6ff0221ddeef03327d24cd77709855c6f2f26..01aadfcedbd1b83e77ca5d97ed8c43fae819f63a 100644
--- a/django/website/tabbed_page/models.py
+++ b/django/website/tabbed_page/models.py
@@ -12,10 +12,10 @@ class TabbedPage(models.Model):
         return self.name
 
 
-class Tab(models.Model):
+class TabInstance(models.Model):
     settings = JSONField(blank=True)
     view_name = models.CharField(max_length=128)
-    page = models.ForeignKey(TabbedPage)
+    page = models.ForeignKey(TabbedPage, related_name='tabs')
     name = models.CharField(max_length=128)
     default = models.BooleanField(default=False)
     position = models.PositiveIntegerField(default=0)
diff --git a/django/website/tabbed_page/tab_pool.py b/django/website/tabbed_page/tab_pool.py
new file mode 100644
index 0000000000000000000000000000000000000000..f3aa1ee98c86eb18852e9dd1ee12d4cf843b7a11
--- /dev/null
+++ b/django/website/tabbed_page/tab_pool.py
@@ -0,0 +1,26 @@
+_pool = {}
+
+
+class MissingTabError(Exception):
+    pass
+
+
+def register_tab(name, tab):
+    global _pool
+    _pool[name] = tab
+
+
+def get_tab(name):
+    global _pool
+
+    try:
+        return _pool[name]
+    except KeyError:
+        raise MissingTabError()
+
+
+def clear_tabs():
+    # Currently only used in test code
+    global _pool
+
+    _pool = {}
diff --git a/django/website/tabbed_page/tests/factories.py b/django/website/tabbed_page/tests/factories.py
index 4ae233e4497e4c657586de4355d231af85114637..8c63caac0a822a457f169b4f1dad2cb1fe19adc3 100644
--- a/django/website/tabbed_page/tests/factories.py
+++ b/django/website/tabbed_page/tests/factories.py
@@ -1,7 +1,7 @@
 from factory.django import DjangoModelFactory
 from factory import fuzzy
 
-from ..models import TabbedPage, Tab
+from ..models import TabbedPage, TabInstance
 
 
 class TabbedPageFactory(DjangoModelFactory):
@@ -11,9 +11,9 @@ class TabbedPageFactory(DjangoModelFactory):
     name = fuzzy.FuzzyText()
 
 
-class TabFactory(DjangoModelFactory):
+class TabInstanceFactory(DjangoModelFactory):
     class Meta:
-        model = Tab
+        model = TabInstance
 
     name = fuzzy.FuzzyText()
     label = fuzzy.FuzzyText()
diff --git a/django/website/tabbed_page/tests/registration_tests.py b/django/website/tabbed_page/tests/registration_tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..587e12da2dab3c952b644d8e93d5224ade8ec85b
--- /dev/null
+++ b/django/website/tabbed_page/tests/registration_tests.py
@@ -0,0 +1,40 @@
+import pytest
+
+from ..tab_pool import (
+    register_tab,
+    get_tab,
+    clear_tabs,
+    MissingTabError,
+)
+
+
+def setup_function(function):
+    clear_tabs()
+
+
+class TestTab(object):
+    pass
+
+
+@pytest.fixture
+def tab():
+    return TestTab()
+
+
+def test_tab_is_registered(tab):
+    register_tab('test-tab', tab)
+    assert get_tab('test-tab') == tab
+
+
+def test_exception_when_tab_not_registered(tab):
+    with pytest.raises(MissingTabError):
+        get_tab('test-tab')
+
+
+def test_registering_twice_overrides_existing_tab(tab):
+    register_tab('test-tab', tab)
+
+    tab2 = TestTab()
+    register_tab('test-tab', tab2)
+
+    assert get_tab('test-tab') == tab2
diff --git a/django/website/tabbed_page/tests/view_tests.py b/django/website/tabbed_page/tests/view_tests.py
index 6adbd83320a4235befe2ff99c2ee61bc4cb35620..29017fc4efa5722d6f0903e6c46a5dd3aa47c5fc 100644
--- a/django/website/tabbed_page/tests/view_tests.py
+++ b/django/website/tabbed_page/tests/view_tests.py
@@ -3,7 +3,7 @@ import pytest
 
 from ..views import TabbedPageView
 
-from .factories import TabbedPageFactory, TabFactory
+from .factories import TabbedPageFactory, TabInstanceFactory
 
 
 @pytest.mark.django_db
@@ -42,9 +42,9 @@ def test_name_defaults_to_main_when_empty():
 @pytest.mark.django_db
 def test_widgets_stored_on_view_in_position_order():
     page = TabbedPageFactory()
-    tab3 = TabFactory(page=page, position=3)
-    tab1 = TabFactory(page=page, position=1)
-    tab2 = TabFactory(page=page, position=2)
+    tab3 = TabInstanceFactory(page=page, position=3)
+    tab1 = TabInstanceFactory(page=page, position=1)
+    tab2 = TabInstanceFactory(page=page, position=2)
 
     view = TabbedPageView()
     view.kwargs = {'name': page.name}
diff --git a/django/website/tabbed_page/views.py b/django/website/tabbed_page/views.py
index 59206fc92633578dda2ce5146def693d6d978864..ffb1e34649bcd0eebc4588c833ff0838f12451d2 100644
--- a/django/website/tabbed_page/views.py
+++ b/django/website/tabbed_page/views.py
@@ -9,7 +9,7 @@ class TabbedPageView(TemplateView):
 
     @property
     def tabs(self):
-        return self.page.tab_set.all().order_by('position')
+        return self.page.tabs.all().order_by('position')
 
     @property
     def page(self):