diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 34583eb..a8526b3 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -14,6 +14,7 @@ from django.contrib.admin.util import (unquote, flatten_fieldsets, get_deleted_o
 from django.contrib.admin import validation
 from django.contrib.admin.templatetags.admin_static import static
 from django.contrib import messages
+from django.utils.http import is_safe_url
 from django.views.decorators.csrf import csrf_protect
 from django.core.exceptions import PermissionDenied, ValidationError, FieldError
 from django.core.paginator import Paginator
@@ -38,6 +39,14 @@ from django.utils.translation import ugettext as _
 from django.utils.translation import ungettext
 from django.utils.encoding import force_text
 
+try:
+    from urllib import parse as urllib_parse
+except ImportError:     # Python 2
+    import urllib as urllib_parse
+    import urlparse
+    urllib_parse.urlparse = urlparse.urlparse
+
+
 HORIZONTAL, VERTICAL = 1, 2
 # returns the <ul> class for a given radio_admin field
 get_ul_class = lambda x: 'radiolist%s' % (' inline' if x == HORIZONTAL else '')
@@ -963,10 +972,17 @@ class ModelAdmin(BaseModelAdmin):
         when editing an existing object.
         """
         opts = self.model._meta
+        changelist_url = reverse('admin:%s_%s_changelist' %
+                                 (opts.app_label, opts.model_name),
+                                 current_app=self.admin_site.name)
+
+        changelist_filters = request.POST.get('_changelist_filters')
+        if changelist_filters:
+            return HttpResponseRedirect(
+                '%s?%s' % (changelist_url, changelist_filters))
+
         if self.has_change_permission(request, None):
-            post_url = reverse('admin:%s_%s_changelist' %
-                               (opts.app_label, opts.model_name),
-                               current_app=self.admin_site.name)
+            post_url = changelist_url
         else:
             post_url = reverse('admin:index',
                                current_app=self.admin_site.name)
@@ -1149,7 +1165,9 @@ class ModelAdmin(BaseModelAdmin):
         ModelForm = self.get_form(request, obj)
         formsets = []
         inline_instances = self.get_inline_instances(request, obj)
+        changelist_filters = None
         if request.method == 'POST':
+            changelist_filters = request.POST.get('_changelist_filters')
             form = ModelForm(request.POST, request.FILES, instance=obj)
             if form.is_valid():
                 form_validated = True
@@ -1188,6 +1206,13 @@ class ModelAdmin(BaseModelAdmin):
                                   queryset=inline.get_queryset(request))
                 formsets.append(formset)
 
+            referer = request.META.get('HTTP_REFERER')
+            if referer:
+                referer = urllib_parse.urlparse(referer)
+                changelist_url = reverse('admin:%s_%s_changelist' % (opts.app_label, opts.model_name))
+                if is_safe_url(url=referer.geturl(), host=request.get_host()) and referer.path.startswith(changelist_url):
+                    changelist_filters = referer.query
+
         adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj),
             self.get_prepopulated_fields(request, obj),
             self.get_readonly_fields(request, obj),
@@ -1214,6 +1239,7 @@ class ModelAdmin(BaseModelAdmin):
             'inline_admin_formsets': inline_admin_formsets,
             'errors': helpers.AdminErrorList(form, formsets),
             'app_label': opts.app_label,
+            'changelist_filters': changelist_filters,
         }
         context.update(extra_context or {})
         return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
@@ -1406,12 +1432,22 @@ class ModelAdmin(BaseModelAdmin):
                                        'obj': force_text(obj_display)},
                               messages.SUCCESS)
 
+            changelist_url = reverse('admin:%s_%s_changelist' %
+                                     (opts.app_label, opts.model_name),
+                                     current_app=self.admin_site.name)
+
+            changelist_filters = request.POST.get('_changelist_filters')
+            if changelist_filters:
+                return HttpResponseRedirect('%s?%s' % (changelist_url, changelist_filters))
+
             if not self.has_change_permission(request, None):
                 return HttpResponseRedirect(reverse('admin:index',
                                                     current_app=self.admin_site.name))
-            return HttpResponseRedirect(reverse('admin:%s_%s_changelist' %
-                                        (opts.app_label, opts.model_name),
-                                        current_app=self.admin_site.name))
+            return HttpResponseRedirect(changelist_url)
+        else:
+            changelist_filters = request.GET.get('_changelist_filters')
+            if changelist_filters:
+                changelist_filters = unquote(changelist_filters)
 
         object_name = force_text(opts.verbose_name)
 
@@ -1429,6 +1465,7 @@ class ModelAdmin(BaseModelAdmin):
             "protected": protected,
             "opts": opts,
             "app_label": app_label,
+            "changelist_filters": changelist_filters,
         }
         context.update(extra_context or {})
 
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
index 4accf80..6870be0 100644
--- a/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -38,6 +38,7 @@
 <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %}
 <div>
 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}
+{% if changelist_filters %}<input type="hidden" name="_changelist_filters" value="{{ changelist_filters }}" />{% endif %}
 {% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
 {% if errors %}
     <p class="errornote">
diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html
index c1a7115..065fa14 100644
--- a/django/contrib/admin/templates/admin/delete_confirmation.html
+++ b/django/contrib/admin/templates/admin/delete_confirmation.html
@@ -36,6 +36,7 @@
     <form action="" method="post">{% csrf_token %}
     <div>
     <input type="hidden" name="post" value="yes" />
+    {% if changelist_filters %}<input type="hidden" name="_changelist_filters" value="{{ changelist_filters }}" />{% endif %}
     <input type="submit" value="{% trans "Yes, I'm sure" %}" />
     </div>
     </form>
diff --git a/django/contrib/admin/templates/admin/submit_line.html b/django/contrib/admin/templates/admin/submit_line.html
index 38a97a1..6ebd155 100644
--- a/django/contrib/admin/templates/admin/submit_line.html
+++ b/django/contrib/admin/templates/admin/submit_line.html
@@ -1,7 +1,14 @@
 {% load i18n admin_urls %}
 <div class="submit-row">
 {% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
-{% if show_delete_link %}<p class="deletelink-box"><a href="{% url opts|admin_urlname:'delete' original.pk|admin_urlquote %}" class="deletelink">{% trans "Delete" %}</a></p>{% endif %}
+{% if show_delete_link %}
+    {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url%}
+    <p class="deletelink-box">
+        <a href="{{ delete_url }}{% if changelist_filters %}?_changelist_filters={{ changelist_filters|admin_urlquote }}{% endif %}" class="deletelink">
+            {% trans "Delete" %}
+        </a>
+    </p>
+{% endif %}
 {% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{%endif%}
 {% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
 {% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py
index cecc6ed..bccf7f2 100644
--- a/django/contrib/admin/templatetags/admin_modify.py
+++ b/django/contrib/admin/templatetags/admin_modify.py
@@ -37,10 +37,12 @@ def submit_row(context):
                             not is_popup and (not save_as or context['add']),
         'show_save_and_continue': not is_popup and context['has_change_permission'],
         'is_popup': is_popup,
-        'show_save': True
+        'show_save': True,
     }
     if context.get('original') is not None:
         ctx['original'] = context['original']
+    if context.get('changelist_filters'):
+        ctx['changelist_filters'] = context['changelist_filters']
     return ctx
 
 @register.filter
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index c0925e0..e853e52 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -4157,3 +4157,97 @@ class AdminUserMessageTest(TestCase):
         self.assertContains(response,
                             '<li class="extra_tag info">Test tags</li>',
                             html=True)
+
+
+@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
+class AdminChangeListRedirectionTests(TestCase):
+    urls = "admin_views.urls"
+    fixtures = ['admin-views-users']
+
+    def setUp(self):
+        Person.objects.create(name="Chris", gender=1, alive=True, age=25)
+        Person.objects.create(name="Jack", gender=2, alive=False, age=47)
+        Person.objects.create(name="Bob", gender=1, alive=True, age=36)
+
+        self.client.login(username='super', password='secret')
+
+    def get_data(self):
+        return {
+            'name': 'Joe', 'gender': '1', 'alive': '1', 'age': '58'
+        }
+
+    def tearDown(self):
+        self.client.logout()
+
+    def get_filters_querystring(self):
+        return urlencode({
+                'alive': 1,
+            })
+
+    def get_filtered_changelist_url(self):
+        return "%s%s?%s" % ('http://testserver', reverse('admin:admin_views_person_changelist'), self.get_filters_querystring())
+
+    def test_change_redirect(self):
+        """
+        Ensure that we're correctly redirected to the filtered changelist
+        after an existing object is saved.
+        Refs #6903.
+        """
+        person = Person.objects.get(name='Chris')
+        change_url = reverse('admin:admin_views_person_change', args=(person.pk,))
+
+        # Simulate clicking an object from a filtered changelist
+        response = self.client.get(change_url, HTTP_REFERER=self.get_filtered_changelist_url())
+        self.assertContains(response, '_changelist_filters')
+        self.assertContains(response, self.get_filters_querystring())
+
+        # Save the object
+        data = self.get_data()
+        data['_save'] = 1
+        data['_changelist_filters'] = self.get_filters_querystring()
+        response = self.client.post(change_url, data)
+
+        # Check that we return to the filtered changelist
+        self.assertRedirects(response, self.get_filtered_changelist_url())
+
+    def test_add_redirect(self):
+        """
+        Ensure that we're correctly redirected to the non-filtered changelist
+        after a new object is added.
+        Refs #6903.
+        """
+        add_url = reverse('admin:admin_views_person_add')
+
+        response = self.client.get(add_url, HTTP_REFERER=self.get_filtered_changelist_url())
+        self.assertNotContains(response, '_changelist_filters')
+        self.assertNotContains(response, self.get_filters_querystring())
+
+        # Add a new object
+        data = self.get_data()
+        data['_save'] = 1
+        data['_changelist_filters'] = self.get_filters_querystring()
+        response = self.client.post(add_url, data)
+
+        # Check that we return to the non-filtered changelist
+        self.assertRedirects(response, reverse('admin:admin_views_person_changelist'))
+
+    def test_delete_redirect(self):
+        """
+        Ensure that we're correctly redirected to the filtered changelist
+        after an existing object is deleted.
+        Refs #6903.
+        """
+        person = Person.objects.get(name='Chris')
+        delete_url = reverse('admin:admin_views_person_delete', args=(person.pk,))
+
+        response = self.client.get(delete_url + '?_changelist_filters=%s' % self.get_filters_querystring())
+        self.assertContains(response, '_changelist_filters')
+        self.assertContains(response, self.get_filters_querystring())
+
+        # Delete the object
+        data = {'post': 'yes', '_changelist_filters': self.get_filters_querystring()}
+        response = self.client.post(delete_url, data)
+
+        # Check that we return to the filtered changelist
+        self.assertRedirects(response, self.get_filtered_changelist_url())
+
