diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -154,7 +154,8 @@
         """
         db = kwargs.get('using')
         if db_field.name in self.raw_id_fields:
-            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel, using=db)
+            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
+                                    self.admin_site, using=db)
         elif db_field.name in self.radio_fields:
             kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                 'class': get_ul_class(self.radio_fields[db_field.name]),
@@ -174,7 +175,8 @@
         db = kwargs.get('using')
 
         if db_field.name in self.raw_id_fields:
-            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db)
+            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
+                                    self.admin_site, using=db)
             kwargs['help_text'] = ''
         elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
             kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -112,29 +112,40 @@
     A Widget for displaying ForeignKeys in the "raw_id" interface rather than
     in a <select> box.
     """
-    def __init__(self, rel, attrs=None, using=None):
+    def __init__(self, rel, admin_site, attrs=None, using=None):
         self.rel = rel
+        self.admin_site = admin_site
         self.db = using
         super(ForeignKeyRawIdWidget, self).__init__(attrs)
 
     def render(self, name, value, attrs=None):
+        rel_to = self.rel.to
         if attrs is None:
             attrs = {}
-        related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
-        params = self.url_parameters()
-        if params:
-            url = u'?' + u'&amp;'.join([u'%s=%s' % (k, v) for k, v in params.items()])
-        else:
-            url = u''
-        if "class" not in attrs:
-            attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
-        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
-        # TODO: "id_" is hard-coded here. This should instead use the correct
-        # API to determine the ID dynamically.
-        output.append(u'<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '
-                      % (related_url, url, name))
-        output.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>'
-                      % (static('admin/img/selector-search.gif'), _('Lookup')))
+        extra = []
+        if rel_to in self.admin_site._registry: # If the related object has an admin interface:
+            try:
+                related_url = reverse('admin:%s_%s_changelist' %
+                                        (rel_to._meta.app_label,
+                                        rel_to._meta.module_name),
+                                        current_app=self.admin_site.name)
+            except NoReverseMatch:
+                raise
+
+            params = self.url_parameters()
+            if params:
+                url = u'?' + u'&amp;'.join([u'%s=%s' % (k, v) for k, v in params.items()])
+            else:
+                url = u''
+            if "class" not in attrs:
+                attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook.
+            # TODO: "lookup_id_" is hard-coded here. This should instead use
+            # the correct API to determine the ID dynamically.
+            extra.append(u'<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '
+                            % (related_url, url, name))
+            extra.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>'
+                            % (static('admin/img/selector-search.gif'), _('Lookup')))
+        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra
         if value:
             output.append(self.label_for_value(value))
         return mark_safe(u''.join(output))
@@ -164,7 +175,8 @@
     def render(self, name, value, attrs=None):
         if attrs is None:
             attrs = {}
-        attrs['class'] = 'vManyToManyRawIdAdminField'
+        if self.rel.to in self.admin_site._registry: # If the related object has an admin interface:
+            attrs['class'] = 'vManyToManyRawIdAdminField'
         if value:
             value = ','.join([force_unicode(v) for v in value])
         else:
@@ -232,8 +244,8 @@
         output = [self.widget.render(name, value, *args, **kwargs)]
         if self.can_add_related:
             related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
-            # TODO: "id_" is hard-coded here. This should instead use the correct
-            # API to determine the ID dynamically.
+            # TODO: "add_id_" is hard-coded here. This should instead use the
+            # correct API to determine the ID dynamically.
             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="%s" width="10" height="10" alt="%s"/></a>'
diff --git a/tests/regressiontests/admin_widgets/models.py b/tests/regressiontests/admin_widgets/models.py
--- a/tests/regressiontests/admin_widgets/models.py
+++ b/tests/regressiontests/admin_widgets/models.py
@@ -67,3 +67,35 @@
     A single car tire. This to test that a user can only select their own cars.
     """
     car = models.ForeignKey(Car)
+
+class Honeycomb(models.Model):
+    location = models.CharField(max_length=20)
+
+class Bee(models.Model):
+    """
+    A model with a FK to a model that won't be registered with the admin
+    (Honeycomb) so the corresponding raw ID widget won't have a magnifying
+    glass link to select related honeycomb instances.
+    """
+    honeycomb = models.ForeignKey(Honeycomb)
+
+class Individual(models.Model):
+    """
+    A model with a FK to itself. It won't be registered with the admin, so the
+    corresponding raw ID widget won't have a magnifying glass link to select
+    related instances (rendering will be called programmatically in this case).
+    """
+    name = models.CharField(max_length=20)
+    parent = models.ForeignKey('self', null=True)
+
+class Company(models.Model):
+    name = models.CharField(max_length=20)
+
+class Advisor(models.Model):
+    """
+    A model with a m2m to a model that won't be registered with the admin
+    (Company) so the corresponding raw ID widget won't have a magnifying
+    glass link to select related company instances.
+    """
+    name = models.CharField(max_length=20)
+    companies = models.ManyToManyField(Company)
diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py
--- a/tests/regressiontests/admin_widgets/tests.py
+++ b/tests/regressiontests/admin_widgets/tests.py
@@ -7,10 +7,6 @@
 from django.conf import settings
 from django.contrib import admin
 from django.contrib.admin import widgets
-from django.contrib.admin.widgets import (FilteredSelectMultiple,
-    AdminSplitDateTime, AdminFileWidget, ForeignKeyRawIdWidget, AdminRadioSelect,
-    RelatedFieldWidgetWrapper, ManyToManyRawIdWidget,
-    url_params_from_lookup_dict)
 from django.core.files.storage import default_storage
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.db.models import DateField
@@ -20,6 +16,7 @@
 from django.utils.unittest import TestCase
 
 import models
+from widgetadmin import site as widget_admin_site
 
 admin_media_prefix = lambda: {
     'ADMIN_MEDIA_PREFIX': "%sadmin/" % settings.STATIC_URL,
@@ -186,22 +183,22 @@
                 'Select a valid choice. That choice is not one of the available choices.')
 
     def test_url_params_from_lookup_dict_any_iterable(self):
-        lookup1 = url_params_from_lookup_dict({'color__in': ('red', 'blue')})
-        lookup2 = url_params_from_lookup_dict({'color__in': ['red', 'blue']})
+        lookup1 = widgets.url_params_from_lookup_dict({'color__in': ('red', 'blue')})
+        lookup2 = widgets.url_params_from_lookup_dict({'color__in': ['red', 'blue']})
         self.assertEqual(lookup1, {'color__in': 'red,blue'})
         self.assertEqual(lookup1, lookup2)
 
 
 class FilteredSelectMultipleWidgetTest(DjangoTestCase):
     def test_render(self):
-        w = FilteredSelectMultiple('test', False)
+        w = widgets.FilteredSelectMultiple('test', False)
         self.assertEqual(
             conditional_escape(w.render('test', 'test')),
             '<select multiple="multiple" name="test" class="selectfilter">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 0, "%(ADMIN_MEDIA_PREFIX)s"); });</script>\n' % admin_media_prefix()
         )
 
     def test_stacked_render(self):
-        w = FilteredSelectMultiple('test', True)
+        w = widgets.FilteredSelectMultiple('test', True)
         self.assertEqual(
             conditional_escape(w.render('test', 'test')),
             '<select multiple="multiple" name="test" class="selectfilterstacked">\n</select><script type="text/javascript">addEvent(window, "load", function(e) {SelectFilter.init("id_test", "test", 1, "%(ADMIN_MEDIA_PREFIX)s"); });</script>\n' % admin_media_prefix()
@@ -210,14 +207,14 @@
 
 class AdminSplitDateTimeWidgetTest(DjangoTestCase):
     def test_render(self):
-        w = AdminSplitDateTime()
+        w = widgets.AdminSplitDateTime()
         self.assertEqual(
             conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))),
             '<p class="datetime">Date: <input value="2007-12-01" type="text" class="vDateField" name="test_0" size="10" /><br />Time: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>',
         )
 
     def test_localization(self):
-        w = AdminSplitDateTime()
+        w = widgets.AdminSplitDateTime()
 
         with self.settings(USE_L10N=True):
             with translation.override('de-at'):
@@ -235,7 +232,7 @@
             name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg'
         )
 
-        w = AdminFileWidget()
+        w = widgets.AdminFileWidget()
         self.assertEqual(
             conditional_escape(w.render('test', album.cover_art)),
             '<p class="file-upload">Currently: <a href="%(STORAGE_URL)salbums/hybrid_theory.jpg">albums\hybrid_theory.jpg</a> <span class="clearable-file-input"><input type="checkbox" name="test-clear" id="test-clear_id" /> <label for="test-clear_id">Clear</label></span><br />Change: <input type="file" name="test" /></p>' % { 'STORAGE_URL': default_storage.url('') },
@@ -255,10 +252,10 @@
         )
         rel = models.Album._meta.get_field('band').rel
 
-        w = ForeignKeyRawIdWidget(rel)
+        w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
         self.assertEqual(
             conditional_escape(w.render('test', band.pk, attrs={})),
-            '<input type="text" name="test" value="%(bandpk)s" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/band/?t=id" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Linkin Park</strong>' % dict(admin_media_prefix(), bandpk=band.pk),
+            '<input type="text" name="test" value="%(bandpk)s" class="vForeignKeyRawIdAdminField" /><a href="/widget_admin/admin_widgets/band/?t=id" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Linkin Park</strong>' % dict(admin_media_prefix(), bandpk=band.pk)
         )
 
     def test_relations_to_non_primary_key(self):
@@ -270,17 +267,42 @@
             barcode=87, name='Core', parent=apple
         )
         rel = models.Inventory._meta.get_field('parent').rel
-        w = ForeignKeyRawIdWidget(rel)
+        w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
         self.assertEqual(
             w.render('test', core.parent_id, attrs={}),
-            '<input type="text" name="test" value="86" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Apple</strong>' % admin_media_prefix(),
+            '<input type="text" name="test" value="86" class="vForeignKeyRawIdAdminField" /><a href="/widget_admin/admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Apple</strong>' % admin_media_prefix()
         )
 
+    def test_fk_related_model_not_in_admin(self):
+        # FK to a model not registered with admin site. Raw ID widget shoud
+        # have no magnifying glass link.
+        big_honeycomb = models.Honeycomb.objects.create(location='Old tree')
+        big_honeycomb.bee_set.create()
+        rel = models.Bee._meta.get_field('honeycomb').rel
+
+        w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
+        self.assertEqual(
+            conditional_escape(w.render('honeycomb_widget', big_honeycomb.pk, attrs={})),
+            '<input type="text" name="honeycomb_widget" value="%(hcombpk)s" />&nbsp;<strong>Honeycomb object</strong>' % {'hcombpk': big_honeycomb.pk}
+        )
+
+    def test_fk_to_self_model_not_in_admin(self):
+        # FK to self, not registered with admin site. Raw ID widget shoud have
+        # no magnifying glass link.
+        subject1 = models.Individual.objects.create(name='Subject #1')
+        models.Individual.objects.create(name='Child', parent=subject1)
+        rel = models.Individual._meta.get_field('parent').rel
+
+        w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
+        self.assertEqual(
+            conditional_escape(w.render('individual_widget', subject1.pk, attrs={})),
+            '<input type="text" name="individual_widget" value="%(subj1pk)s" />&nbsp;<strong>Individual object</strong>' % {'subj1pk': subject1.pk}
+        )
 
     def test_proper_manager_for_label_lookup(self):
         # see #9258
         rel = models.Inventory._meta.get_field('parent').rel
-        w = ForeignKeyRawIdWidget(rel)
+        w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
 
         hidden = models.Inventory.objects.create(
             barcode=93, name='Hidden', hidden=True
@@ -290,31 +312,28 @@
         )
         self.assertEqual(
             w.render('test', child_of_hidden.parent_id, attrs={}),
-            '<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Hidden</strong>' % admin_media_prefix(),
+            '<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField" /><a href="/widget_admin/admin_widgets/inventory/?t=barcode" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>&nbsp;<strong>Hidden</strong>' % admin_media_prefix()
         )
 
 
 class ManyToManyRawIdWidgetTest(DjangoTestCase):
     def test_render(self):
         band = models.Band.objects.create(name='Linkin Park')
-        band.album_set.create(
-            name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg'
-        )
 
         m1 = models.Member.objects.create(name='Chester')
         m2 = models.Member.objects.create(name='Mike')
         band.members.add(m1, m2)
         rel = models.Band._meta.get_field('members').rel
 
-        w = ManyToManyRawIdWidget(rel)
+        w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
         self.assertEqual(
             conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})),
-            '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" /><a href="../../../admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk),
+            '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" /><a href="/widget_admin/admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="/static/admin/img/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk)
         )
 
         self.assertEqual(
             conditional_escape(w.render('test', [m1.pk])),
-            '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" /><a href="../../../admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk),
+            '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" /><a href="/widget_admin/admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk)
         )
 
         self.assertEqual(w._has_changed(None, None), False)
@@ -324,10 +343,31 @@
         self.assertEqual(w._has_changed([1, 2], [u'1']), True)
         self.assertEqual(w._has_changed([1, 2], [u'1', u'3']), True)
 
+    def test_m2m_related_model_not_in_admin(self):
+        # M2M relatinship with model not registered with admin site. Raw ID
+        # widget shoud have no magnifying glass link.
+        consultor1 = models.Advisor.objects.create(name='Rockstar Techie')
+
+        c1 = models.Company.objects.create(name='Doodle')
+        c2 = models.Company.objects.create(name='Pear')
+        consultor1.companies.add(c1, c2)
+        rel = models.Advisor._meta.get_field('companies').rel
+
+        w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
+        self.assertEqual(
+            conditional_escape(w.render('company_widget1', [c1.pk, c2.pk], attrs={})),
+            '<input type="text" name="company_widget1" value="%(c1pk)s,%(c2pk)s" />' % {'c1pk': c1.pk, 'c2pk': c2.pk}
+        )
+
+        self.assertEqual(
+            conditional_escape(w.render('company_widget2', [c1.pk])),
+            '<input type="text" name="company_widget2" value="%(c1pk)s" />' % {'c1pk': c1.pk}
+        )
+
 class RelatedFieldWidgetWrapperTests(DjangoTestCase):
     def test_no_can_add_related(self):
-        rel = models.Inventory._meta.get_field('parent').rel
-        w = AdminRadioSelect()
+        rel = models.Individual._meta.get_field('parent').rel
+        w = widgets.AdminRadioSelect()
         # Used to fail with a name error.
-        w = RelatedFieldWidgetWrapper(w, rel, admin.site)
+        w = widgets.RelatedFieldWidgetWrapper(w, rel, widget_admin_site)
         self.assertFalse(w.can_add_related)
diff --git a/tests/regressiontests/admin_widgets/widgetadmin.py b/tests/regressiontests/admin_widgets/widgetadmin.py
--- a/tests/regressiontests/admin_widgets/widgetadmin.py
+++ b/tests/regressiontests/admin_widgets/widgetadmin.py
@@ -27,4 +27,14 @@
 site.register(models.User)
 site.register(models.Car, CarAdmin)
 site.register(models.CarTire, CarTireAdmin)
+
+site.register(models.Member)
+site.register(models.Band)
 site.register(models.Event, EventAdmin)
+site.register(models.Album)
+
+site.register(models.Inventory)
+
+site.register(models.Bee)
+
+site.register(models.Advisor)
