Index: django/contrib/admin/filterspecs.py
===================================================================
--- django/contrib/admin/filterspecs.py	(revision 4767)
+++ django/contrib/admin/filterspecs.py	(working copy)
@@ -55,7 +55,7 @@
         else:
             self.lookup_title = f.verbose_name
         self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name)
-        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
+        self.lookup_val = params.get(self.lookup_kwarg, None)
         self.lookup_choices = f.rel.to._default_manager.all()
 
     def has_output(self):
@@ -80,7 +80,7 @@
     def __init__(self, f, request, params, model):
         super(ChoicesFilterSpec, self).__init__(f, request, params, model)
         self.lookup_kwarg = '%s__exact' % f.name
-        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
+        self.lookup_val = params.get(self.lookup_kwarg, None)
 
     def choices(self, cl):
         yield {'selected': self.lookup_val is None,
@@ -133,8 +133,8 @@
         super(BooleanFieldFilterSpec, self).__init__(f, request, params, model)
         self.lookup_kwarg = '%s__exact' % f.name
         self.lookup_kwarg2 = '%s__isnull' % f.name
-        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
-        self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None)
+        self.lookup_val = params.get(self.lookup_kwarg, None)
+        self.lookup_val2 = params.get(self.lookup_kwarg2, None)
 
     def title(self):
         return self.field.verbose_name
@@ -157,7 +157,7 @@
 class AllValuesFilterSpec(FilterSpec):
     def __init__(self, f, request, params, model):
         super(AllValuesFilterSpec, self).__init__(f, request, params, model)
-        self.lookup_val = request.GET.get(f.name, None)
+        self.lookup_val = params.get(f.name, None)
         self.lookup_choices = model._meta.admin.manager.distinct().order_by(f.name).values(f.name)
 
     def title(self):
Index: django/contrib/admin/views/main.py
===================================================================
--- django/contrib/admin/views/main.py	(revision 4767)
+++ django/contrib/admin/views/main.py	(working copy)
@@ -12,8 +12,10 @@
 from django.http import Http404, HttpResponse, HttpResponseRedirect
 from django.utils.html import escape
 from django.utils.text import capfirst, get_text_list
+from django.conf import settings
 import operator
 
+
 from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
 if not LogEntry._meta.installed:
     raise ImproperlyConfigured, "You'll need to put 'django.contrib.admin' in your INSTALLED_APPS setting before you can use the admin application."
@@ -33,6 +35,7 @@
 SEARCH_VAR = 'q'
 IS_POPUP_VAR = 'pop'
 ERROR_FLAG = 'e'
+SESSION_RESTORE_VAR = 'sr'
 
 # Text to display within change-list table cells if the value is blank.
 EMPTY_CHANGELIST_VALUE = '(None)'
@@ -235,7 +238,7 @@
     if post_url is None:
         if request.user.has_perm(app_label + '.' + opts.get_change_permission()):
             # redirect to list view
-            post_url = '../'
+            post_url = '../?sr'
         else:
             # Object list will give 'Permission Denied', so go back to admin home
             post_url = '../../../'
@@ -357,7 +360,7 @@
                 return HttpResponseRedirect("../add/")
             else:
                 request.user.message_set.create(message=msg)
-                return HttpResponseRedirect("../")
+                return HttpResponseRedirect("../?sr")
     else:
         # Populate new_data with a "flattened" version of the current data.
         new_data = manipulator.flatten_data()
@@ -512,7 +515,7 @@
         obj.delete()
         LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, object_id, obj_display, DELETION)
         request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display})
-        return HttpResponseRedirect("../../")
+        return HttpResponseRedirect("../../?sr")
     extra_context = {
         "title": _("Are you sure?"),
         "object_name": opts.verbose_name,
@@ -554,25 +557,49 @@
         self.manager = self.opts.admin.manager
 
         # Get search parameters from the query string.
+        self.set_params(request, model)
+        self.order_field, self.order_type = self.get_ordering()
+        self.query_set = self.get_query_set()
+        self.get_results(request)
+        self.title = (self.is_popup and _('Select %s') % self.opts.verbose_name or _('Select %s to change') % self.opts.verbose_name)
+        self.filter_specs, self.has_filters = self.get_filters(request)
+        self.pk_attname = self.lookup_opts.pk.attname
+
+    def set_params(self, request, model):
+        query = request.GET.copy()
+        restore = SESSION_RESTORE_VAR in request.GET
+        sessions = 'django.contrib.sessions' in settings.INSTALLED_APPS
+
+        # restore from session if requested
+        if sessions:
+            saved = request.session.setdefault('change_list_params', {}) \
+                .setdefault(model._meta.app_label,{}) \
+                .setdefault(model._meta.object_name, {})
+            if restore:
+                for key in saved:
+                    query.setdefault(key, saved[key])
         try:
-            self.page_num = int(request.GET.get(PAGE_VAR, 0))
+            self.page_num = int(query.get(PAGE_VAR, 0))
         except ValueError:
             self.page_num = 0
-        self.show_all = request.GET.has_key(ALL_VAR)
-        self.is_popup = request.GET.has_key(IS_POPUP_VAR)
-        self.params = dict(request.GET.items())
+        self.show_all = query.has_key(ALL_VAR)
+        self.is_popup = query.has_key(IS_POPUP_VAR)
+        self.params = dict(query.items())
+
         if self.params.has_key(PAGE_VAR):
             del self.params[PAGE_VAR]
         if self.params.has_key(ERROR_FLAG):
             del self.params[ERROR_FLAG]
+        if restore:
+            del self.params[SESSION_RESTORE_VAR]
+        self.query = query.get(SEARCH_VAR, '')
 
-        self.order_field, self.order_type = self.get_ordering()
-        self.query = request.GET.get(SEARCH_VAR, '')
-        self.query_set = self.get_query_set()
-        self.get_results(request)
-        self.title = (self.is_popup and _('Select %s') % self.opts.verbose_name or _('Select %s to change') % self.opts.verbose_name)
-        self.filter_specs, self.has_filters = self.get_filters(request)
-        self.pk_attname = self.lookup_opts.pk.attname
+        # save session
+        if sessions:
+            # make sure session gets saved
+            request.session['change_list_params_changed'] = 1
+            for key in self.params:
+                saved[key] = self.params[key]
 
     def get_filters(self, request):
         filter_specs = []
Index: django/contrib/sessions/middleware.py
===================================================================
--- django/contrib/sessions/middleware.py	(revision 4767)
+++ django/contrib/sessions/middleware.py	(working copy)
@@ -36,6 +36,11 @@
     def get(self, key, default=None):
         return self._session.get(key, default)
 
+    def setdefault(self, key, default):
+        if not key in self:
+            self[key] = default
+        return self[key]
+
     def set_test_cookie(self):
         self[TEST_COOKIE_NAME] = TEST_COOKIE_VALUE
 
Index: django/contrib/admin/templates/admin/change_form.html
===================================================================
--- django/contrib/admin/templates/admin/change_form.html	(revision 4767)
+++ django/contrib/admin/templates/admin/change_form.html	(working copy)
@@ -11,7 +11,7 @@
 {% block breadcrumbs %}{% if not is_popup %}
 <div class="breadcrumbs">
      <a href="../../../">{% trans "Home" %}</a> &rsaquo;
-     <a href="../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
+     <a href="../?sr">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
      {% if add %}{% trans "Add" %} {{ opts.verbose_name|escape }}{% else %}{{ original|truncatewords:"18"|escape }}{% endif %}
 </div>
 {% endif %}{% endblock %}
