From a603e672dedf99df8d3f64d6123dcaf28cd8c2de Mon Sep 17 00:00:00 2001
From: Hugo Osvaldo Barrera <hugo@barrera.io>
Date: Wed, 27 Jan 2016 21:43:04 -0300
Subject: [PATCH] Add links when using raw_id_fields in admin

Closes #7923
---
 django/contrib/admin/widgets.py | 19 ++++++++++++++++++-
 tests/admin_widgets/tests.py    |  9 ++++++---
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 3424e7f..a2df938 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -11,6 +11,7 @@ from django.forms.utils import flatatt
 from django.forms.widgets import RadioFieldRenderer
 from django.template.loader import render_to_string
 from django.urls import reverse
+from django.urls.exceptions import NoReverseMatch
 from django.utils import six
 from django.utils.encoding import force_text
 from django.utils.html import (
@@ -194,7 +195,23 @@ class ForeignKeyRawIdWidget(forms.TextInput):
         key = self.rel.get_related_field().name
         try:
             obj = self.rel.model._default_manager.using(self.db).get(**{key: value})
-            return '&nbsp;<strong>%s</strong>' % escape(Truncator(obj).words(14, truncate='...'))
+            change_url = reverse(
+                '%s:%s_%s_change' % (
+                    self.admin_site.name,
+                    obj._meta.app_label,
+                    obj._meta.object_name.lower(),
+                ),
+                args=(obj.pk,)
+            )
+            return '&nbsp;<strong><a href="%s">%s</a></strong>' % (
+                change_url,
+                escape(Truncator(obj).words(14, truncate='...')),
+            )
+        except NoReverseMatch:
+            # Admin not registered for target model:
+            return '&nbsp;<strong>%s</strong>' % (
+                escape(Truncator(obj).words(14, truncate='...')),
+            )
         except (ValueError, self.rel.model.DoesNotExist):
             return ''
 
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index cbaeaa8..ce79dde 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -480,7 +480,8 @@ class ForeignKeyRawIdWidgetTest(TestCase):
             '<input type="text" name="test" value="%(bandpk)s" '
             'class="vForeignKeyRawIdAdminField" />'
             '<a href="/admin_widgets/band/?_to_field=id" class="related-lookup" '
-            'id="lookup_id_test" title="Lookup"></a>&nbsp;<strong>Linkin Park</strong>'
+            'id="lookup_id_test" title="Lookup"></a>&nbsp;<strong>'
+            '<a href="/admin_widgets/band/1/change/">Linkin Park</a></strong>'
             % {'bandpk': band.pk}
         )
 
@@ -500,7 +501,8 @@ class ForeignKeyRawIdWidgetTest(TestCase):
             'class="vForeignKeyRawIdAdminField" />'
             '<a href="/admin_widgets/inventory/?_to_field=barcode" '
             'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
-            '&nbsp;<strong>Apple</strong>'
+            '&nbsp;<strong><a href="/admin_widgets/inventory/1/change/">'
+            'Apple</a></strong>'
         )
 
     def test_fk_related_model_not_in_admin(self):
@@ -549,7 +551,8 @@ class ForeignKeyRawIdWidgetTest(TestCase):
             '<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField" />'
             '<a href="/admin_widgets/inventory/?_to_field=barcode" '
             'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
-            '&nbsp;<strong>Hidden</strong>'
+            '&nbsp;<strong><a href="/admin_widgets/inventory/1/change/">'
+            'Hidden</a></strong>'
         )
 
 
-- 
2.7.0

