diff --git a/bluebottle/activities/documents.py b/bluebottle/activities/documents.py
index 8f3b74b66e..0a4a054bd6 100644
--- a/bluebottle/activities/documents.py
+++ b/bluebottle/activities/documents.py
@@ -1,6 +1,7 @@
 from builtins import str
 from builtins import object
-from django_elasticsearch_dsl import DocType, fields
+
+from bluebottle.initiatives.documents import DocType, fields
 
 from bluebottle.utils.documents import MultiTenantIndex
 from bluebottle.activities.models import Activity
diff --git a/bluebottle/auth/middleware.py b/bluebottle/auth/middleware.py
index 488486885a..2eaa5a3c99 100644
--- a/bluebottle/auth/middleware.py
+++ b/bluebottle/auth/middleware.py
@@ -1,4 +1,3 @@
-from builtins import object
 import json
 import logging
 from calendar import timegm
@@ -12,6 +11,7 @@
 from django.http.request import RawPostDataException
 from django.shortcuts import render_to_response
 from django.utils import timezone
+from django.utils.deprecation import MiddlewareMixin
 from lockdown import settings as lockdown_settings
 from lockdown.middleware import (LockdownMiddleware as BaseLockdownMiddleware,
                                  compile_url_exceptions, get_lockdown_form)
@@ -32,7 +32,7 @@ def isAdminRequest(request):
     return request.path.startswith('/downloads') or base_path in ['jet', 'admin', 'jet-dashboard']
 
 
-class UserJwtTokenMiddleware(object):
+class UserJwtTokenMiddleware(MiddlewareMixin):
     """
     Custom middleware to set the User on the request when using
     Jwt Token authentication.
@@ -41,7 +41,8 @@ class UserJwtTokenMiddleware(object):
     def process_request(self, request):
         """ Override only the request to add the user """
         try:
-            return request.user
+            request.user
+            return
         except AttributeError:
             pass
 
@@ -64,7 +65,7 @@ def process_request(self, request):
             return
 
 
-class SlidingJwtTokenMiddleware(object):
+class SlidingJwtTokenMiddleware(MiddlewareMixin):
     """
     Custom middleware to set a sliding window for the jwt auth token expiration.
     """
@@ -177,7 +178,7 @@ def process_request(self, request):
             super(AdminOnlyAuthenticationMiddleware, self).process_request(request)
 
 
-class AdminOnlyCsrf(object):
+class AdminOnlyCsrf(MiddlewareMixin):
     """
     Disable csrf for non-Admin requests, eg API
     """
@@ -280,7 +281,7 @@ def process_request(self, request):
 authorization_logger = logging.getLogger(__name__)
 
 
-class LogAuthFailureMiddleWare(object):
+class LogAuthFailureMiddleWare(MiddlewareMixin):
     def process_request(self, request):
         # TODO: Handle this more cleanly. The exception is raised when using IE11.
         #       Possibly related to the following issue:
diff --git a/bluebottle/bb_accounts/views.py b/bluebottle/bb_accounts/views.py
index 466225f14a..3124f1275f 100644
--- a/bluebottle/bb_accounts/views.py
+++ b/bluebottle/bb_accounts/views.py
@@ -17,7 +17,10 @@
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.exceptions import PermissionDenied, NotAuthenticated, ValidationError
 
-from rest_framework_jwt.views import ObtainJSONWebToken
+try:
+    from rest_framework_jwt.views import ObtainJSONWebToken
+except ImportError:
+    from rest_framework_jwt.views import ObtainJSONWebTokenView as ObtainJSONWebToken
 
 from rest_framework_json_api.views import AutoPrefetchMixin
 
diff --git a/bluebottle/bluebottle_dashboard/templates/admin/change_list.html b/bluebottle/bluebottle_dashboard/templates/admin/change_list.html
index f79338065d..8aea16b06f 100644
--- a/bluebottle/bluebottle_dashboard/templates/admin/change_list.html
+++ b/bluebottle/bluebottle_dashboard/templates/admin/change_list.html
@@ -1,5 +1,5 @@
 {% extends "admin:admin/change_list.html" %}
-{% load i18n admin_static admin_list %}
+{% load i18n static admin_list %}
 {% load admin_urls %}
 {% load humanize %}
 {% load admin_extra %}
diff --git a/bluebottle/bluebottle_drf2/middleware.py b/bluebottle/bluebottle_drf2/middleware.py
index ad60815179..8d2aae48ab 100644
--- a/bluebottle/bluebottle_drf2/middleware.py
+++ b/bluebottle/bluebottle_drf2/middleware.py
@@ -1,8 +1,9 @@
-from builtins import object
+from django.utils.deprecation import MiddlewareMixin
+
 METHOD_OVERRIDE_HEADER = 'HTTP_X_HTTP_METHOD_OVERRIDE'
 
 
-class MethodOverrideMiddleware(object):
+class MethodOverrideMiddleware(MiddlewareMixin):
     def process_view(self, request, callback, callback_args, callback_kwargs):
         if request.method != 'POST':
             return
diff --git a/bluebottle/bluebottle_drf2/renderers.py b/bluebottle/bluebottle_drf2/renderers.py
index 9f34fea991..27662510b2 100644
--- a/bluebottle/bluebottle_drf2/renderers.py
+++ b/bluebottle/bluebottle_drf2/renderers.py
@@ -12,7 +12,11 @@
 )
 from rest_framework.settings import api_settings
 
-from rest_framework_json_api.compat import collections_abc
+try:
+    import collections.abc as collections_abc
+except ImportError:
+    import collections as collections_abc
+
 from rest_framework_json_api.relations import HyperlinkedMixin, ResourceRelatedField, SkipDataMixin
 from rest_framework_json_api.renderers import JSONRenderer
 from rest_framework_json_api import utils
diff --git a/bluebottle/clients/__init__.py b/bluebottle/clients/__init__.py
index ba787d262b..79af7079da 100644
--- a/bluebottle/clients/__init__.py
+++ b/bluebottle/clients/__init__.py
@@ -5,8 +5,6 @@
 from django.conf import settings
 from django.utils._os import safe_join
 
-from tenant_schemas.postgresql_backend.base import FakeTenant
-
 
 logger = logging.getLogger(__name__)
 
@@ -35,6 +33,8 @@ def set_tenant(self, tenant):
                      self.tenant_properties)
 
         except (ImportError, AttributeError, IOError):
+            from tenant_schemas.postgresql_backend.base import FakeTenant
+
             if not isinstance(tenant, FakeTenant):
                 logger.debug('No tenant properties found for: {0}'.format(tenant.client_name))
 
diff --git a/bluebottle/clients/middleware.py b/bluebottle/clients/middleware.py
index 48cbcc525f..9ea3db3db1 100644
--- a/bluebottle/clients/middleware.py
+++ b/bluebottle/clients/middleware.py
@@ -1,14 +1,14 @@
 from future import standard_library
 standard_library.install_aliases()
-from builtins import object
 from urllib.parse import urljoin
 
 from django.db import connection
 from django.conf import settings
 from django.shortcuts import redirect
+from django.utils.deprecation import MiddlewareMixin
 
 
-class MediaMiddleware(object):
+class MediaMiddleware(MiddlewareMixin):
     def process_response(self, request, response):
         if (
             response.status_code == 404 and
diff --git a/bluebottle/cms/templates/admin/edit_inline/stacked-nested.html b/bluebottle/cms/templates/admin/edit_inline/stacked-nested.html
index 26329104e9..6b3908e36c 100644
--- a/bluebottle/cms/templates/admin/edit_inline/stacked-nested.html
+++ b/bluebottle/cms/templates/admin/edit_inline/stacked-nested.html
@@ -1,4 +1,4 @@
-{% load i18n admin_urls admin_static django_template_additions %}
+{% load i18n admin_urls static django_template_additions %}
 <div class="js-inline-admin-formset sortable sortable-ui inline-group{% if recursive_formset %} {{ recursive_formset.formset.prefix|default:"Root" }}-nested-inline {% if prev_prefix %} {{ prev_prefix }}-{{ loopCounter }}-nested-inline{% endif %} nested-inline{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-group">
 {% with recursive_formset=inline_admin_formset stacked_template='admin/edit_inline/stacked-nested.html' tabular_template='admin/edit_inline/tabular-nested.html'%}
   <h2>{{ recursive_formset.opts.verbose_name_plural|title }}</h2>
diff --git a/bluebottle/common/admin_utils.py b/bluebottle/common/admin_utils.py
index 8e42f63e68..5f3a70d616 100644
--- a/bluebottle/common/admin_utils.py
+++ b/bluebottle/common/admin_utils.py
@@ -58,9 +58,8 @@ def label_for_value(self, value):
 
 
 class ImprovedModelForm(admin.ModelAdmin):
-    def formfield_for_dbfield(self, db_field, **kwargs):
+    def formfield_for_dbfield(self, db_field, request=None, **kwargs):
         if db_field.name in self.raw_id_fields:
-            kwargs.pop("request", None)
             type = db_field.rel.__class__.__name__
             if type == "ManyToOneRel":
                 kwargs['widget'] = VerboseForeignKeyRawIdWidget(db_field.rel,
@@ -69,5 +68,7 @@ def formfield_for_dbfield(self, db_field, **kwargs):
                 kwargs['widget'] = VerboseManyToManyRawIdWidget(db_field.rel,
                                                                 site)
             return db_field.formfield(**kwargs)
+        if request:
+            kwargs["request"] = request
         return super(ImprovedModelForm, self).formfield_for_dbfield(db_field,
                                                                     **kwargs)
diff --git a/bluebottle/exports/templates/exportdb/base.html b/bluebottle/exports/templates/exportdb/base.html
index 31332d1f7f..479bba451c 100755
--- a/bluebottle/exports/templates/exportdb/base.html
+++ b/bluebottle/exports/templates/exportdb/base.html
@@ -1,4 +1,4 @@
-{% extends "admin/base_site.html" %}{% load i18n admin_static %}
+{% extends "admin/base_site.html" %}{% load i18n static %}
 
 {% block extrahead %}{{ block.super }}
 {% if jquery_in_vendor %}
diff --git a/bluebottle/exports/templates/exportdb/in_progress.html b/bluebottle/exports/templates/exportdb/in_progress.html
index e5cfe02b3d..72461a78c0 100755
--- a/bluebottle/exports/templates/exportdb/in_progress.html
+++ b/bluebottle/exports/templates/exportdb/in_progress.html
@@ -1,4 +1,4 @@
-{% extends "exportdb/base.html" %}{% load i18n admin_static %}
+{% extends "exportdb/base.html" %}{% load i18n static %}
 
 {% block extrahead %}{{ block.super }}
 <style type="text/css">
diff --git a/bluebottle/files/views.py b/bluebottle/files/views.py
index dfd1d92f2d..a22c98209a 100644
--- a/bluebottle/files/views.py
+++ b/bluebottle/files/views.py
@@ -15,7 +15,10 @@
 from bluebottle.files.serializers import FileSerializer, ImageSerializer, PrivateFileSerializer
 from bluebottle.utils.views import CreateAPIView, RetrieveAPIView
 
-mime = magic.Magic(mime=True)
+try:
+    mime = magic.Magic(mime=True)
+except TypeError:
+    mime = magic.Magic()
 
 
 class FileList(AutoPrefetchMixin, CreateAPIView):
diff --git a/bluebottle/fsm/forms.py b/bluebottle/fsm/forms.py
index 15ab9cf643..3d0d958658 100644
--- a/bluebottle/fsm/forms.py
+++ b/bluebottle/fsm/forms.py
@@ -17,8 +17,9 @@ class StateWidget(forms.TextInput):
 
 class StateMachineModelFormMetaClass(ModelFormMetaclass):
     def __new__(cls, name, bases, attrs):
-        if 'Meta' in attrs:
-            for field, machine in list(attrs['Meta'].model._state_machines.items()):
+        model = getattr(attrs.get('Meta', None), 'model', None)
+        if hasattr(model, '_state_machines'):
+            for field, machine in list(model._state_machines.items()):
                 attrs[field] = forms.ChoiceField(
                     required=False,
                     widget=TransitionSelectWidget()
diff --git a/bluebottle/funding/admin.py b/bluebottle/funding/admin.py
index d590184763..5af532af2c 100644
--- a/bluebottle/funding/admin.py
+++ b/bluebottle/funding/admin.py
@@ -110,7 +110,7 @@ class PayoutInline(StateMachineAdminMixin, admin.TabularInline):
     extra = 0
     can_delete = False
 
-    def has_add_permission(self, request):
+    def has_add_permission(self, request, obj=None):
         return False
 
     def payout_link(self, obj):
@@ -642,7 +642,7 @@ class DonorInline(PaymentLinkMixin, admin.TabularInline):
     extra = 0
     can_delete = False
 
-    def has_add_permission(self, request):
+    def has_add_permission(self, request, obj=None):
         return False
 
 
diff --git a/bluebottle/funding/documents.py b/bluebottle/funding/documents.py
index 1fc0dac43a..131fdfd4ad 100644
--- a/bluebottle/funding/documents.py
+++ b/bluebottle/funding/documents.py
@@ -18,6 +18,8 @@ class Meta(object):
         model = Funding
         related_models = (Initiative, Member, Donor)
 
+    Django = Meta
+
     def get_instances_from_related(self, related_instance):
         if isinstance(related_instance, Initiative):
             return Funding.objects.filter(initiative=related_instance)
diff --git a/bluebottle/funding/templates/admin/funding/payment/change_form.html b/bluebottle/funding/templates/admin/funding/payment/change_form.html
index 7ab8be3546..438beede16 100644
--- a/bluebottle/funding/templates/admin/funding/payment/change_form.html
+++ b/bluebottle/funding/templates/admin/funding/payment/change_form.html
@@ -1,5 +1,5 @@
 {% extends "admin/change_form.html" %}
-{% load i18n admin_static admin_list admin_urls %}
+{% load i18n static admin_list admin_urls %}
 
 {% block object-tools-items %}
     {% if original.can_update %}
diff --git a/bluebottle/funding_stripe/templates/admin/funding_stripe/stripepayoutaccount/change_form.html b/bluebottle/funding_stripe/templates/admin/funding_stripe/stripepayoutaccount/change_form.html
index 6b71eab880..fa4702463e 100644
--- a/bluebottle/funding_stripe/templates/admin/funding_stripe/stripepayoutaccount/change_form.html
+++ b/bluebottle/funding_stripe/templates/admin/funding_stripe/stripepayoutaccount/change_form.html
@@ -1,5 +1,5 @@
 {% extends "admin/change_form.html" %}
-{% load i18n admin_static admin_list admin_urls %}
+{% load i18n static admin_list admin_urls %}
 
 {% block object-tools-items %}
     <li>
diff --git a/bluebottle/initiatives/documents.py b/bluebottle/initiatives/documents.py
index 1dfc5891d2..7ce3d5d506 100644
--- a/bluebottle/initiatives/documents.py
+++ b/bluebottle/initiatives/documents.py
@@ -1,5 +1,10 @@
 from builtins import object
-from django_elasticsearch_dsl import DocType, fields
+
+try:
+    from django_elasticsearch_dsl.documents import DocType
+except ImportError:
+    from django_elasticsearch_dsl import DocType
+from django_elasticsearch_dsl import fields
 
 from bluebottle.time_based.models import PeriodActivity, DateActivity
 from bluebottle.utils.documents import MultiTenantIndex
@@ -95,6 +100,8 @@ class Meta(object):
             DateActivity
         )
 
+    Django = Meta
+
     def get_queryset(self):
         return super(InitiativeDocument, self).get_queryset().select_related(
             'theme', 'place', 'owner', 'promoter',
diff --git a/bluebottle/members/admin.py b/bluebottle/members/admin.py
index e6d6aa50f2..03062a0bab 100644
--- a/bluebottle/members/admin.py
+++ b/bluebottle/members/admin.py
@@ -7,6 +7,7 @@
 from django import forms
 from django.conf.urls import url
 from django.contrib import admin
+from django.contrib.admin.sites import NotRegistered
 from django.contrib.auth.admin import UserAdmin, GroupAdmin
 from django.contrib.auth.models import Group, Permission
 from django.contrib.auth.tokens import default_token_generator
@@ -203,7 +204,7 @@ class UserActivityInline(admin.TabularInline):
 
     formset = LimitModelFormset
 
-    def has_add_permission(self, request):
+    def has_add_permission(self, request, obj=None):
         return False
 
 
@@ -577,5 +578,8 @@ class TokenAdmin(admin.ModelAdmin):
     fields = ('user', 'key')
 
 
-admin.site.unregister(Token)
+try:
+    admin.site.unregister(Token)
+except NotRegistered:
+    pass
 admin.site.register(Token, TokenAdmin)
diff --git a/bluebottle/members/serializers.py b/bluebottle/members/serializers.py
index f65fc64e83..301a65acb3 100644
--- a/bluebottle/members/serializers.py
+++ b/bluebottle/members/serializers.py
@@ -1,5 +1,4 @@
 from builtins import object
-from axes.attempts import is_already_locked
 from django import forms
 from django.conf import settings
 from django.contrib.auth import get_user_model, password_validation, authenticate
@@ -23,6 +22,11 @@
 from bluebottle.tasks.models import Skill
 from bluebottle.utils.serializers import PermissionField, TruncatedCharField, CaptchaField
 
+try:
+    from axes.attempts import is_already_locked
+except ImportError:
+    is_already_locked = lambda request: request.axes_locked_out
+
 BB_USER_MODEL = get_user_model()
 
 
diff --git a/bluebottle/notifications/admin.py b/bluebottle/notifications/admin.py
index 30133e558b..4a322803d4 100644
--- a/bluebottle/notifications/admin.py
+++ b/bluebottle/notifications/admin.py
@@ -23,7 +23,7 @@ class MessageAdminInline(GenericTabularInline):
     readonly_fields = ['sent', 'subject', 'recipient']
     fields = readonly_fields
 
-    def has_add_permission(self, request):
+    def has_add_permission(self, request, obj=None):
         return False
 
     extra = 0
diff --git a/bluebottle/redirects/middleware.py b/bluebottle/redirects/middleware.py
index 2cfbe2713d..5017cfe948 100644
--- a/bluebottle/redirects/middleware.py
+++ b/bluebottle/redirects/middleware.py
@@ -1,17 +1,17 @@
 from __future__ import unicode_literals
 
-from builtins import object
 import regex
 
 from django import http
 from django.conf import settings
 from django.db import connection
+from django.utils.deprecation import MiddlewareMixin
 
 from bluebottle.redirects.models import Redirect
 from bluebottle.clients import properties
 
 
-class RedirectFallbackMiddleware(object):
+class RedirectFallbackMiddleware(MiddlewareMixin):
     """
     A modified version of django.contrib.redirects, this app allows
     us to optionally redirect users using regular expressions.
diff --git a/bluebottle/scim/templates/admin/scim/scimplatformsettings/change_form.html b/bluebottle/scim/templates/admin/scim/scimplatformsettings/change_form.html
index fee92445b4..311caf596a 100644
--- a/bluebottle/scim/templates/admin/scim/scimplatformsettings/change_form.html
+++ b/bluebottle/scim/templates/admin/scim/scimplatformsettings/change_form.html
@@ -1,5 +1,5 @@
 {% extends "admin/change_form.html" %}
-{% load i18n admin_static admin_list admin_urls %}
+{% load i18n static admin_list admin_urls %}
 
 {% block object-tools-items %}
     <li>
diff --git a/bluebottle/settings/base.py b/bluebottle/settings/base.py
index 33477ef7c9..241aac6946 100644
--- a/bluebottle/settings/base.py
+++ b/bluebottle/settings/base.py
@@ -118,7 +118,7 @@
                 'tenant_extras.template_loaders.FilesystemLoader',
                 'django.template.loaders.filesystem.Loader',
                 'django.template.loaders.app_directories.Loader',
-                'django.template.loaders.eggs.Loader',
+                # 'django.template.loaders.eggs.Loader',
                 'admin_tools.template_loaders.Loader',
             ],
             'context_processors': [
@@ -149,7 +149,7 @@
     'bluebottle.clients.middleware.MediaMiddleware',
     'tenant_extras.middleware.TenantLocaleMiddleware',
     'bluebottle.redirects.middleware.RedirectFallbackMiddleware',
-    'bluebottle.auth.middleware.UserJwtTokenMiddleware',
+    'bluebottle.auth.middleware.UserJwtTokenMiddleware',  # 'Member' object has no attribute 'has_header'
     'bluebottle.utils.middleware.SubDomainSessionMiddleware',
     'bluebottle.utils.middleware.APILanguageMiddleware',
     'bluebottle.auth.middleware.AdminOnlySessionMiddleware',
diff --git a/bluebottle/urls/i18n_urls.py b/bluebottle/urls/i18n_urls.py
index 13750c08ee..767667bae3 100644
--- a/bluebottle/urls/i18n_urls.py
+++ b/bluebottle/urls/i18n_urls.py
@@ -1,6 +1,6 @@
+from django import VERSION
 from django.conf.urls import include, url
 from django.contrib import admin
-from django.contrib.auth.views import password_reset_done, password_reset_confirm
 from django.core.urlresolvers import reverse_lazy
 from django.views.generic import RedirectView
 
@@ -9,10 +9,23 @@
 from bluebottle.bluebottle_dashboard.views import locked_out
 from bluebottle.looker.dashboard_views import LookerEmbedView  # noqa This has to be imported early so that custom urls will work
 
+try:
+    from django.contrib.auth.views import password_reset_done, password_reset_confirm
+except ImportError:
+    from django.contrib.auth.views import PasswordResetDoneView, PasswordResetConfirmView
+    password_reset_done = PasswordResetDoneView.as_view()
+    password_reset_confirm = PasswordResetConfirmView.as_view()
 
 admin.autodiscover()
 
 
+def dj1_include_with_namespace(dotted, namespace):
+    if VERSION >= (2, 0):
+        return include(dotted)
+    else:
+        return include(dotted, namespace)
+
+
 urlpatterns = [
 
     # Django JET URLS
@@ -41,7 +54,7 @@
 
     # account login/logout, password reset, and password change
     url(r'^accounts/',
-        include('django.contrib.auth.urls', namespace='accounts')),
+        dj1_include_with_namespace('django.contrib.auth.urls', namespace='accounts')),
 
     url(r'^admin/summernote/', include('django_summernote.urls')),
     url(r'^admin', RedirectView.as_view(url=reverse_lazy('admin:index')), name='admin-slash'),
diff --git a/bluebottle/utils/managers.py b/bluebottle/utils/managers.py
index 089a52ada8..9653748784 100644
--- a/bluebottle/utils/managers.py
+++ b/bluebottle/utils/managers.py
@@ -5,11 +5,15 @@
 from django.db.models.query import QuerySet
 from django.db.models.query_utils import Q
 from django.utils.timezone import now
-from django_subquery.expressions import Subquery, OuterRef
 from parler.managers import TranslatableQuerySet, TranslatableManager
 from polymorphic.managers import PolymorphicManager
 from polymorphic.query import PolymorphicQuerySet
 
+try:
+    from django.db.models.expressions import Subquery, OuterRef
+except ImportError:
+    from django_subquery.expressions import Subquery, OuterRef
+
 
 class GenericForeignKeyManagerMixin(object):
     """
diff --git a/bluebottle/utils/templates/utils/admin/total_amount_change_list.html b/bluebottle/utils/templates/utils/admin/total_amount_change_list.html
index ea43e4e09b..2626877600 100644
--- a/bluebottle/utils/templates/utils/admin/total_amount_change_list.html
+++ b/bluebottle/utils/templates/utils/admin/total_amount_change_list.html
@@ -1,5 +1,5 @@
 {% extends "admin/change_list.html" %}
-{% load i18n admin_static admin_list %}
+{% load i18n static admin_list %}
 {% load admin_urls %}
 {% load humanize %}
 
diff --git a/bluebottle/utils/validators.py b/bluebottle/utils/validators.py
index e935d410db..29955d7b37 100644
--- a/bluebottle/utils/validators.py
+++ b/bluebottle/utils/validators.py
@@ -21,7 +21,10 @@
 logger = logging.getLogger(__name__)
 
 
-mime = magic.Magic(mime=True)
+try:
+    mime = magic.Magic(mime=True)
+except TypeError:
+    mime = magic.Magic()
 
 # Can safely add more post code form fields here.
 postal_code_mapping = {
diff --git a/bluebottle/utils/views.py b/bluebottle/utils/views.py
index edc24ca8b1..5bf37f7dba 100644
--- a/bluebottle/utils/views.py
+++ b/bluebottle/utils/views.py
@@ -28,7 +28,10 @@
 from .models import Language
 from .serializers import LanguageSerializer
 
-mime = magic.Magic(mime=True)
+try:
+    mime = magic.Magic(mime=True)
+except TypeError:
+    mime = magic.Magic()
 
 
 class TagList(views.APIView):
diff --git a/bluebottle/wallposts/admin.py b/bluebottle/wallposts/admin.py
index bfa95e72d0..2a0abf1a66 100644
--- a/bluebottle/wallposts/admin.py
+++ b/bluebottle/wallposts/admin.py
@@ -195,9 +195,9 @@ class WallpostParentAdmin(PolymorphicParentModelAdmin):
         'author__first_name', 'author__last_name', 'ip_address'
     )
     child_models = (
-        (MediaWallpost, MediaWallpostAdmin),
-        (TextWallpost, TextWallpostAdmin),
-        (SystemWallpost, SystemWallpostAdmin),
+        MediaWallpost,
+        TextWallpost,
+        SystemWallpost,
     )
 
     def type(self, obj):
@@ -310,5 +310,5 @@ def wallpost(self, obj):
         url = reverse('admin:wallposts_wallpost_change', args=(obj.id,))
         return format_html(u'<a href="{}">{}</a>', url, obj)
 
-    def has_add_permission(self, request):
+    def has_add_permission(self, request, obj=None):
         return False
diff --git a/setup.py b/setup.py
index d09b64d8cc..05ff22c220 100755
--- a/setup.py
+++ b/setup.py
@@ -49,6 +49,7 @@ def read_file(name):
     'django-memoize==2.1.0',
     'django-modeltranslation==0.12.1',
     'django-money==0.15.1',
+    'django-nested-inline==0.4.2',
     'django-parler==1.9.2',
     'django-permissions-widget==1.5.1',
     'django_polymorphic==1.2',