Index: django/contrib/admin/helpers.py
===================================================================
--- django/contrib/admin/helpers.py	(revision 13020)
+++ django/contrib/admin/helpers.py	(working copy)
@@ -12,8 +12,8 @@
 from django.utils.html import escape, conditional_escape
 from django.utils.safestring import mark_safe
 from django.utils.translation import ugettext_lazy as _
+from django.core.urlresolvers import reverse, NoReverseMatch
 
-
 ACTION_CHECKBOX_NAME = '_selected_action'
 
 class ActionForm(forms.Form):
@@ -186,6 +186,29 @@
                     result_repr = display_for_field(value, f)
         return conditional_escape(result_repr)
 
+    def change_url(self):
+        """ Return admin change URL for field if applicable. """
+        field, obj, model_admin = \
+            self.field['field'], self.form.instance, self.model_admin
+        try:
+            f, attr, value = lookup_field(field, obj, model_admin)
+        except (AttributeError, ValueError, ObjectDoesNotExist):
+            return None
+        else:
+            rel = getattr(f,'rel')
+            if rel and rel.to in model_admin.admin_site._registry:
+                try:
+                    return reverse('admin:%s_%s_change' % (
+                            rel.to._meta.app_label,
+                            rel.to._meta.object_name.lower()),
+                                   args=(value.pk,),
+                                   current_app=model_admin.admin_site.name)
+                except NoReverseMatch:
+                    return None # fail silently
+            else:
+                return None # not a related field
+
+    
 class InlineAdminFormSet(object):
     """
     A wrapper around an inline formset for use in the admin system.
Index: django/contrib/admin/widgets.py
===================================================================
--- django/contrib/admin/widgets.py	(revision 13020)
+++ django/contrib/admin/widgets.py	(working copy)
@@ -242,6 +242,31 @@
             output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
                 (related_url, name))
             output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="%s"/></a>' % (settings.ADMIN_MEDIA_PREFIX, _('Add Another')))
+
+            if value: # (a related object is selected)
+                try:
+                    related_object = rel_to.objects.get(pk=value)
+                except:
+                    # probably a TypeError (e.g. value is list for
+                    # multiple-select widgets), but fail silently regardless
+                    pass
+                else:
+                    try:
+                        change_related_url = reverse(
+                            'admin:%s_%s_change' % info,
+                            args=(related_object.id,),
+                            current_app=self.admin_site.name)
+                    except NoReverseMatch:
+                        # fail silently
+                        pass
+                    else:
+                        params = {
+                            'url': change_related_url,
+                            'admin_media_prefix': settings.ADMIN_MEDIA_PREFIX,
+                            'text': _('edit %s' % related_object),
+                            }
+                        output.append(u' <a href="%(url)s" class="change_link"><img src="%(admin_media_prefix)simg/admin/icon_changelink.gif" width="10" height="10" alt="%(text)s" title="%(text)s"/> %(text)s</a>' % params)
+                
         return mark_safe(u''.join(output))
 
     def build_attrs(self, extra_attrs=None, **kwargs):
Index: django/contrib/admin/templates/admin/edit_inline/tabular.html
===================================================================
--- django/contrib/admin/templates/admin/edit_inline/tabular.html	(revision 13020)
+++ django/contrib/admin/templates/admin/edit_inline/tabular.html	(working copy)
@@ -44,7 +45,7 @@
             {% for field in line %}
               <td class="{{ field.field.name }}">
               {% if field.is_readonly %}
-                  <p>{{ field.contents }}</p>
+                  <p>{{ field.contents }} {% if field.change_url %}<a href="{{ field.change_url }}" class="readonly_field_change_link"><img src="{% admin_media_prefix %}img/admin/icon_changelink.gif" width="10" height="10" alt="{% trans "edit" %}" title="{% trans "edit" %}"/></a>{% endif %}</p>
               {% else %}
                   {{ field.field.errors.as_ul }}
                   {{ field.field }}
Index: django/contrib/admin/templates/admin/includes/fieldset.html
===================================================================
--- django/contrib/admin/templates/admin/includes/fieldset.html	(revision 13020)
+++ django/contrib/admin/templates/admin/includes/fieldset.html	(working copy)
@@ -1,3 +1,4 @@
+{% load i18n adminmedia %}
 <fieldset class="module aligned {{ fieldset.classes }}">
     {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
     {% if fieldset.description %}
@@ -13,7 +14,7 @@
                     {% else %}
                         {{ field.label_tag }}
                         {% if field.is_readonly %}
-                            <p>{{ field.contents }}</p>
+                            <p>{{ field.contents }} {% if field.change_url %}<a href="{{ field.change_url }}" class="readonly_field_change_link"><img src="{% admin_media_prefix %}img/admin/icon_changelink.gif" width="10" height="10" alt="{% trans "edit" %}" title="{% trans "edit" %}"/></a>{% endif %}</p>
                         {% else %}
                             {{ field.field }}
                         {% endif %}
