diff --git a/README.rst b/README.rst
index f55940c9..f8f44ab4 100644
--- a/README.rst
+++ b/README.rst
@@ -43,11 +43,11 @@ Requirements
 
 - Python (2.7, 3.3 - 3.5)
 
-- Django (1.6 - 1.11)
+- Django (1.8 - 1.11)
 
 - Django REST Framework (3.2 - 3.6)
 
-- Django Filters (0.11 - 1.0)
+- Django Filters (1.0)
 
 Development Installation
 ------------------------
diff --git a/docs/deployment/upgrading.rst b/docs/deployment/upgrading.rst
index 2c2766c5..d368509d 100644
--- a/docs/deployment/upgrading.rst
+++ b/docs/deployment/upgrading.rst
@@ -59,94 +59,14 @@ management commands:
 Upgrade Your Database
 ---------------------
 
-Migrations of the database can be tricky. Prior to `v1.0.0`__, database
-migrations were provided by way of manual, SQL migration scripts. After this
-release, Patchwork moved to support `Django migrations`__.  If you are
-upgrading from `v1.0.0` or later, it is likely that you can rely entirely on
-the later to bring your database up-to-date. This can be done like so:
+New versions of Patchwork may provide a number of schema and/or data migrations
+which must be applied before starting the instance. To do this, run the
+*migrate* management command:
 
 .. code-block:: shell
 
    $ ./manage.py migrate
 
-However, there are a number of scenarios in which you may need to fall back to
-the provided SQL migrations or provide your own:
+For more information on migrations, refer to `the Django documentation`__.
 
-* You are using Django < 1.6
-
-  Patchwork supports Django 1.6. However, Django Migrations was added in 1.7
-  and is `not available for previous versions`__. As such, you must continue to
-  use manual migrations or upgrade your version of Django. For many of the
-  migrations, this can be done automatically:
-
-  .. code-block:: shell
-
-     $ ./manage.py sqlmigrate patchwork 0003_add_check_model
-
-  However, this only works for schema migrations. For data migrations,
-  however, this will fail. In this cases, these migrations will need to be
-  handwritten.
-
-* You are using Django > 1.6, but upgrading from Patchwork < 1.0.0
-
-  Patchwork only started providing migrations in `v1.0.0`. SQL migrations are
-  provided for versions prior to this and must be applied to get the database
-  to the "initial" state that Django migrations expects.
-
-* You have diverged from upstream Patchwork
-
-  If you have applied custom patches that change the database models, the
-  database in an "inconsistent state" and the provided migrations will likely
-  fail to apply.
-
-Steps to handle the latter two of these are described below.
-
-__ https://github.com/getpatchwork/patchwork/releases/tag/v1.0.0
-__ https://docs.djangoproject.com/en/1.8/topics/migrations/
-__ http://blog.allenap.me/2015/05/south-south-2-and-django-migrations.html
-
-Upgrading a pre-v1.0.0 Patchwork instance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The process for this type of upgrade is quite simple: upgrade using manual SQL
-upgrades until better options become available. As such, you should apply all
-unapplied SQL migrations that are not duplicated by Django migrations.  Once
-such duplication occurs, rely on the Django migrations only and continue to do
-so going forward.
-
-Upgrading a "diverged" Patchwork instance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This type of upgrade is a little trickier. There are two options you can take:
-
-1. Bring your Patchwork instance back in sync with upstream
-
-2. Provide your own migrations
-
-The former option is particularly suitable if you decide to upstream your
-change or decide it's not valuable enough to retain. This will require either
-reworking any migrations that exist prior to your feature being upstreamed, or
-deleting any added database fields and tables, respectively. In both cases,
-manually, hand-written SQL migrations will be required to get the databse into
-a consistent state (remember: **backup**!). Once this is done, you can resume
-using the upstream-provided migrations, ensuring any Django migrations that you
-may have skipped are not applied again:
-
-.. code-block:: shell
-
-   $ ./manage.py migrate 000x-abc --fake  # when 000x-abc is last "skippable"
-
-It's worth adding that with the databases now back in sync it should be
-possible to return to using upstream code rather than maintaining a fork.
-
-The latter option is best chosen if you wish to retain the aforementioned fork.
-How you do this depends on the extensiveness of your changes, but getting the
-latest version of Patchwork, deleting the provided migrations, applying any
-patches you may have and regenerating the migrations seems like the best
-option.
-
-.. note::
-
-   To prevent the latter case above from occurring, we'd ask that you submit
-   any patches you may have to the upstream Patchwork so that the wider
-   community can benefit from this new functionality.
+__ https://docs.djangoproject.com/en/1.11/topics/migrations/
diff --git a/docs/development/installation.rst b/docs/development/installation.rst
index 70d3145f..30fdb547 100644
--- a/docs/development/installation.rst
+++ b/docs/development/installation.rst
@@ -70,7 +70,7 @@ To run specific tox targets or tests, pass arguments to the above:
 
 .. code-block:: shell
 
-   $ docker-compose run --rm web --quick-tox -e py27-django17 \
+   $ docker-compose run --rm web --quick-tox -e py27-django18 \
        patchwork.tests.test_bundles
 
 To run all tests, including Selenium UI interaction tests, using only the
diff --git a/patchwork/api/cover.py b/patchwork/api/cover.py
index 2a7651f4..10645048 100644
--- a/patchwork/api/cover.py
+++ b/patchwork/api/cover.py
@@ -19,7 +19,6 @@
 
 import email.parser
 
-import django
 from rest_framework.generics import ListAPIView
 from rest_framework.generics import RetrieveAPIView
 from rest_framework.serializers import HyperlinkedModelSerializer
@@ -78,15 +77,9 @@ class CoverLetterList(ListAPIView):
     ordering = 'id'
 
     def get_queryset(self):
-        qs = CoverLetter.objects.all().prefetch_related('series')\
-            .select_related('project', 'submitter')
-
-        # FIXME(stephenfin): This causes issues with Django 1.6 for whatever
-        # reason. Suffer the performance hit on those versions.
-        if django.VERSION >= (1, 7):
-            qs.defer('content', 'headers')
-
-        return qs
+        return CoverLetter.objects.all().prefetch_related('series')\
+            .select_related('project', 'submitter')\
+            .defer('content', 'headers')
 
 
 class CoverLetterDetail(RetrieveAPIView):
diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py
index 198d64f4..15dff5fd 100644
--- a/patchwork/api/filters.py
+++ b/patchwork/api/filters.py
@@ -23,7 +23,6 @@ from django_filters import IsoDateTimeFilter
 from django_filters import ModelChoiceFilter
 from django.forms import ModelChoiceField
 
-from patchwork.compat import LOOKUP_FIELD
 from patchwork.models import Bundle
 from patchwork.models import Check
 from patchwork.models import CoverLetter
@@ -37,8 +36,8 @@ from patchwork.models import State
 class TimestampMixin(FilterSet):
 
     # TODO(stephenfin): These should filter on a 'updated_at' field instead
-    before = IsoDateTimeFilter(name='date', **{LOOKUP_FIELD: 'lt'})
-    since = IsoDateTimeFilter(name='date', **{LOOKUP_FIELD: 'gte'})
+    before = IsoDateTimeFilter(name='date', lookup_expr='lt')
+    since = IsoDateTimeFilter(name='date', lookup_expr='gte')
 
 
 class ProjectChoiceField(ModelChoiceField):
diff --git a/patchwork/api/patch.py b/patchwork/api/patch.py
index cb829c7d..1922cf5b 100644
--- a/patchwork/api/patch.py
+++ b/patchwork/api/patch.py
@@ -57,7 +57,6 @@ class StateField(RelatedField):
         'incorrect_type': _('Incorrect type. Expected string value, received '
                             '{data_type}.'),
     }
-    queryset = ''  # django 1.6, rest_framework 3.2 require this
 
     def to_internal_value(self, data):
         try:
@@ -151,8 +150,6 @@ class PatchList(ListAPIView):
     ordering = 'id'
 
     def get_queryset(self):
-        # TODO(stephenfin): Does the defer here cause issues with Django 1.6
-        # (like /cover)?
         return Patch.objects.all()\
             .prefetch_related('series', 'check_set')\
             .select_related('project', 'state', 'submitter', 'delegate')\
diff --git a/patchwork/compat.py b/patchwork/compat.py
index 177e79e3..38caa4e8 100644
--- a/patchwork/compat.py
+++ b/patchwork/compat.py
@@ -23,25 +23,6 @@ import django
 from django.conf import settings
 
 
-# render_to_string
-#
-# The render_to_string function no longer accepts the dictionary and
-# context_instance parameters in Django 1.10.
-#
-# https://docs.djangoproject.com/en/dev/releases/1.8/
-
-if django.VERSION >= (1, 8):
-    from django.template.loader import render_to_string  # noqa
-else:
-    from django.template import loader  # noqa
-    from django.template import RequestContext  # noqa
-
-    def render_to_string(template_name, context=None, request=None):
-        context_instance = RequestContext(request) if request else None
-        return loader.render_to_string(template_name, context,
-                                       context_instance)
-
-
 # DjangoFilterBackend
 #
 # The DjangoFilterBackend was provided in Django REST Framework from 3.0 to
@@ -60,24 +41,6 @@ if settings.ENABLE_REST_API:
         from rest_framework.filters import DjangoFilterBackend  # noqa
 
 
-# LOOKUP_FIELD
-#
-# The django-filter library uses the 'lookup_expr' attribute to determine which
-# lookup type to use, e.g. exact, gt, lt etc. However, until 0.13 this was
-# called 'lookup_type', and 0.13 supported both but gave a deprecation warning.
-# We need to support these versions for use with older versions of DRF.
-#
-# https://github.com/carltongibson/django-filter/blob/v0.13/django_filters\
-#   /filters.py#L35-L36
-if settings.ENABLE_REST_API:
-    import django_filters  # noqa
-
-    if django_filters.VERSION >= (1, 0):
-        LOOKUP_FIELD = 'lookup_expr'
-    else:
-        LOOKUP_FIELD = 'lookup_type'
-
-
 # reverse, reverse_lazy
 #
 # The reverse and reverse_lazy functions have been moved to django.urls in
diff --git a/patchwork/models.py b/patchwork/models.py
index 7d413d93..84d8ddeb 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -572,12 +572,8 @@ class Comment(EmailMixin, models.Model):
 
     def save(self, *args, **kwargs):
         super(Comment, self).save(*args, **kwargs)
-        # NOTE(stephenfin): Mitigate an issue with Python 3.4 + Django 1.6
-        try:
-            if hasattr(self.submission, 'patch'):
-                self.submission.patch.refresh_tag_counts()
-        except Patch.DoesNotExist:
-            pass
+        if hasattr(self.submission, 'patch'):
+            self.submission.patch.refresh_tag_counts()
 
     def delete(self, *args, **kwargs):
         super(Comment, self).delete(*args, **kwargs)
@@ -994,8 +990,3 @@ class PatchChangeNotification(models.Model):
                                  on_delete=models.CASCADE)
     last_modified = models.DateTimeField(default=datetime.datetime.now)
     orig_state = models.ForeignKey(State, on_delete=models.CASCADE)
-
-
-if django.VERSION < (1, 7):
-    # We don't have support for AppConfig in Django 1.6.x
-    import patchwork.signals  # noqa
diff --git a/patchwork/notifications.py b/patchwork/notifications.py
index 840d2cf9..88e96628 100644
--- a/patchwork/notifications.py
+++ b/patchwork/notifications.py
@@ -27,8 +27,8 @@ from django.contrib.sites.models import Site
 from django.core.mail import EmailMessage
 from django.db.models import Count
 from django.db.models import Q
+from django.template.loader import render_to_string
 
-from patchwork.compat import render_to_string
 from patchwork.models import EmailConfirmation
 from patchwork.models import EmailOptout
 from patchwork.models import PatchChangeNotification
diff --git a/patchwork/templates/patchwork/patch-list.html b/patchwork/templates/patchwork/patch-list.html
index c645ec85..71c1ba92 100644
--- a/patchwork/templates/patchwork/patch-list.html
+++ b/patchwork/templates/patchwork/patch-list.html
@@ -4,8 +4,6 @@
 {% load project %}
 {% load static %}
 
-{% load cycle from compat %}
-
 {% include "patchwork/filters.html" %}
 
 {% include "patchwork/pagination.html" %}
diff --git a/patchwork/templates/patchwork/projects.html b/patchwork/templates/patchwork/projects.html
index d75077d4..9ce1918c 100644
--- a/patchwork/templates/patchwork/projects.html
+++ b/patchwork/templates/patchwork/projects.html
@@ -1,5 +1,4 @@
 {% extends "base.html" %}
-{% load cycle from compat %}
 
 {% block title %}Project List{% endblock %}
 {% block body %}
diff --git a/patchwork/templatetags/compat.py b/patchwork/templatetags/compat.py
deleted file mode 100644
index 7b210e8d..00000000
--- a/patchwork/templatetags/compat.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Patchwork - automated patch tracking system
-# Copyright (C) 2016 Stephen Finucane <stephen@that.guru>
-#
-# This file is part of the Patchwork package.
-#
-# Patchwork is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# Patchwork is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Patchwork; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-"""Compatibility wrappers for various Django versions."""
-
-import django
-from django.template import defaulttags
-from django.template import Library
-
-
-register = Library()
-
-
-# cycle
-#
-# The cycle template tag enables auto-escaping by default in 1.8, with
-# deprecations enabled in 1.7. A 'future' library is provided in 1.6
-# to mitigate this, but it is removed in 1.10. Provide our own version
-# of 'future' to ensure this works in all versions of Django supported.
-#
-# https://docs.djangoproject.com/en/dev/releases/1.6/
-# https://docs.djangoproject.com/en/dev/releases/1.10/
-
-@register.tag
-def cycle(parser, token):
-    if django.VERSION < (1, 8):
-        return defaulttags.cycle(parser, token, escape=True)
-    else:
-        return defaulttags.cycle(parser, token)
diff --git a/patchwork/tests/browser.py b/patchwork/tests/browser.py
index 3ea3266b..1939defb 100644
--- a/patchwork/tests/browser.py
+++ b/patchwork/tests/browser.py
@@ -21,10 +21,7 @@ import errno
 import os
 import time
 
-try:
-    from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-except:  # Django < 1.7
-    from django.test import LiveServerTestCase as StaticLiveServerTestCase
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
 from selenium.common.exceptions import (
     NoSuchElementException, StaleElementReferenceException,
     TimeoutException)
diff --git a/patchwork/views/mail.py b/patchwork/views/mail.py
index 49c79727..8afd83b3 100644
--- a/patchwork/views/mail.py
+++ b/patchwork/views/mail.py
@@ -23,8 +23,8 @@ from django.conf import settings as conf_settings
 from django.core.mail import send_mail
 from django.http import HttpResponseRedirect
 from django.shortcuts import render
+from django.template.loader import render_to_string
 
-from patchwork.compat import render_to_string
 from patchwork.compat import reverse
 from patchwork.forms import EmailForm
 from patchwork.models import EmailConfirmation
diff --git a/patchwork/views/user.py b/patchwork/views/user.py
index d99fedf0..408ba10e 100644
--- a/patchwork/views/user.py
+++ b/patchwork/views/user.py
@@ -27,8 +27,8 @@ from django.core.mail import send_mail
 from django.http import HttpResponseRedirect
 from django.shortcuts import get_object_or_404
 from django.shortcuts import render
+from django.template.loader import render_to_string
 
-from patchwork.compat import render_to_string
 from patchwork.compat import reverse
 from patchwork.filters import DelegateFilter
 from patchwork.forms import EmailForm
diff --git a/releasenotes/notes/remove-django-1-6-and-1-7-support-7f77e45668c39aae.yaml b/releasenotes/notes/remove-django-1-6-and-1-7-support-7f77e45668c39aae.yaml
new file mode 100644
index 00000000..ca9d9d19
--- /dev/null
+++ b/releasenotes/notes/remove-django-1-6-and-1-7-support-7f77e45668c39aae.yaml
@@ -0,0 +1,8 @@
+---
+upgrade:
+  - |
+    Django 1.6 and 1.7 are no longer supported. These are no longer supported
+    upstream and most distributions provide a newer version.
+  - |
+    django-filter 0.11 is no longer supported. This was only used with Django
+    1.6 and 1.7 and is not compatible with any version supported by Patchwork.
diff --git a/tox.ini b/tox.ini
index 976789ea..bd8af767 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,17 +1,11 @@
 [tox]
 minversion = 2.0
-envlist = pep8,py{27,34}-django{16,17,18,19,110,111},py35-django{18,19,110,111}
+envlist = pep8,py{27,34,35}-django{18,19,110,111}
 skipsdist = True
 
 [testenv]
 deps =
     -r{toxinidir}/requirements-test.txt
-    django16: django>=1.6,<1.7
-    django16: djangorestframework>=3.2,<3.3
-    django16: django-filter>=0.11,<0.12
-    django17: django>=1.7,<1.8
-    django17: djangorestframework>=3.3,<3.4
-    django17: django-filter>=0.11,<0.12
     django18: django>=1.8,<1.9
     django19: django>=1.9,<1.10
     django110: django>=1.10,<1.11
