Index: django/contrib/admin/options.py
===================================================================
--- django/contrib/admin/options.py	(revision 7900)
+++ django/contrib/admin/options.py	(working copy)
@@ -15,6 +15,7 @@
 from django.utils.text import capfirst, get_text_list
 from django.utils.translation import ugettext as _
 from django.utils.encoding import force_unicode
+from urllib import quote
 import sets
 
 HORIZONTAL, VERTICAL = 1, 2
@@ -394,7 +395,9 @@
             # Figure out where to redirect. If the user has change permission,
             # redirect to the change-list page for this object. Otherwise,
             # redirect to the admin index.
-            if self.has_change_permission(request, None):
+            if 'admin_change_return_to' in request.GET:
+                post_url = request.GET['admin_change_return_to']
+            elif self.has_change_permission(request, None):
                 post_url = '../'
             else:
                 post_url = '../../../'
@@ -459,7 +462,11 @@
             return HttpResponseRedirect("../add/")
         else:
             request.user.message_set.create(message=msg)
-            return HttpResponseRedirect("../")
+            if 'admin_change_return_to' in request.GET:
+                post_url = request.GET['admin_change_return_to']
+            else:
+                post_url = '../'
+            return HttpResponseRedirect(post_url)
     save_change = transaction.commit_on_success(save_change)
 
     def render_change_form(self, request, model, context, add=False, change=False, form_url='', obj=None):
@@ -508,6 +515,11 @@
         inline_formsets = []
         obj = self.model()
         if request.method == 'POST':
+            if 'admin_change_return_to' in request.GET:
+                return_to = request.GET['admin_change_return_to']
+            else:
+                return_to = None
+            
             form = ModelForm(request.POST, request.FILES)
             for FormSet in self.get_formsets(request):
                 inline_formset = FormSet(data=request.POST, files=request.FILES,
@@ -520,7 +532,14 @@
             for FormSet in self.get_formsets(request):
                 inline_formset = FormSet(instance=obj)
                 inline_formsets.append(inline_formset)
+            if 'HTTP_REFERER' in request.META:
+                return_to = request.META['HTTP_REFERER']
+            else:
+                return_to = None
 
+        if return_to:
+            form_url = form_url + '?admin_change_return_to=%s' % quote(return_to)
+
         adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
         media = self.media + adminForm.media
         for fs in inline_formsets:
@@ -543,7 +562,7 @@
             'root_path': self.admin_site.root_path,
         }
         context.update(extra_context or {})
-        return self.render_change_form(request, model, context, add=True)
+        return self.render_change_form(request, model, context, form_url=form_url, add=True)
 
     def change_view(self, request, object_id, extra_context=None):
         "The 'change' admin view for this model."
@@ -571,6 +590,11 @@
         ModelForm = self.get_form(request, obj)
         inline_formsets = []
         if request.method == 'POST':
+            if 'admin_change_return_to' in request.GET:
+                return_to = request.GET['admin_change_return_to']
+            else:
+                return_to = None
+            
             form = ModelForm(request.POST, request.FILES, instance=obj)
             for FormSet in self.get_formsets(request, obj):
                 inline_formset = FormSet(request.POST, request.FILES, instance=obj)
@@ -583,6 +607,15 @@
             for FormSet in self.get_formsets(request, obj):
                 inline_formset = FormSet(instance=obj)
                 inline_formsets.append(inline_formset)
+            if 'HTTP_REFERER' in request.META:
+                return_to = request.META['HTTP_REFERER']
+            else:
+                return_to = None
+        
+        if return_to:
+            form_url = '?admin_change_return_to=%s' % quote(return_to)
+        else:
+            form_url = ''
 
         ## Populate the FormWrapper.
         #oldform = oldforms.FormWrapper(manipulator, new_data, errors)
@@ -620,8 +653,8 @@
             'errors': AdminErrorList(form, inline_formsets),
             'root_path': self.admin_site.root_path,
         }
-        context.update(extra_context or {})
-        return self.render_change_form(request, model, context, change=True, obj=obj)
+        context.update(extra_context or {}) 
+        return self.render_change_form(request, model, context, change=True, form_url=form_url, obj=obj)
 
     def changelist_view(self, request, extra_context=None):
         "The 'change list' admin view for this model."
