diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 6ab842dd61..48b93166c8 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -250,7 +250,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
 
         if callable(self.view_on_site):
             return self.view_on_site(obj)
-        elif self.view_on_site:
+        elif self.view_on_site and hasattr(obj, 'get_absolute_url'):
             # use the ContentType lookup if view_on_site is True
             return reverse('admin:view_on_site', kwargs={
                 'content_type_id': ContentType.objects.get_for_model(obj).pk,
diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py
index e2b6a00261..e0e2a6fc08 100644
--- a/tests/admin_views/models.py
+++ b/tests/admin_views/models.py
@@ -745,11 +745,17 @@ class City(models.Model):
     state = models.ForeignKey(State)
     name = models.CharField(max_length=100)
 
+    def get_absolute_url(self):
+        return '/dummy/%s/' % self.pk
+
 
 class Restaurant(models.Model):
     city = models.ForeignKey(City)
     name = models.CharField(max_length=100)
 
+    def get_absolute_url(self):
+        return '/dummy/%s/' % self.pk
+
 
 class Worker(models.Model):
     work_at = models.ForeignKey(Restaurant)
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 0ec9f25479..f23d8d1960 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -13,6 +13,7 @@ from django.core.exceptions import ImproperlyConfigured
 from django.core.urlresolvers import reverse, NoReverseMatch
 # Register auth models with the admin.
 from django.contrib.auth import get_permission_codename
+from django.contrib.admin import ModelAdmin
 from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
 from django.contrib.admin.models import LogEntry, DELETION
 from django.contrib.admin.sites import LOGIN_FORM_KEY
@@ -4641,6 +4642,11 @@ class AdminViewOnSiteTest(TestCase):
                             '"/worker/%s/%s/"' % (worker.surname, worker.name),
                             )
 
+    def test_missing_get_absolute_url(self):
+        "Ensure None is returned if model doesn't have get_absolute_url"
+        model_admin = ModelAdmin(Worker, None)
+        self.assertIsNone(model_admin.get_view_on_site_url(Worker()))
+
 
 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
 class InlineAdminViewOnSiteTest(TestCase):