diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py
index 7e9047f..501f0ef 100644
--- a/django/views/generic/detail.py
+++ b/django/views/generic/detail.py
@@ -15,6 +15,8 @@ class SingleObjectMixin(object):
     queryset = None
     slug_field = 'slug'
     context_object_name = None
+    slug_url_kwarg = 'slug'
+    pk_url_kwarg = 'pk'
 
     def get_object(self, queryset=None):
         """
@@ -29,8 +31,8 @@ class SingleObjectMixin(object):
             queryset = self.get_queryset()
 
         # Next, try looking up by primary key.
-        pk = self.kwargs.get('pk', None)
-        slug = self.kwargs.get('slug', None)
+        pk = self.kwargs.get(self.pk_url_kwarg, None)
+        slug = self.kwargs.get(self.slug_url_kwarg, None)
         if pk is not None:
             queryset = queryset.filter(pk=pk)
 
diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt
index e9f3152..132913f 100644
--- a/docs/ref/class-based-views.txt
+++ b/docs/ref/class-based-views.txt
@@ -136,6 +136,16 @@ SingleObjectMixin
         The name of the field on the model that contains the slug. By default,
         ``slug_field`` is ``'slug'``.
 
+    .. attribute:: slug_url_kwarg
+
+        The name of the URLConf keyword argument that contains the slug. By
+        default, ``slug_url_kwarg`` is ``'slug'``.
+
+    .. attribute:: pk_url_kwarg
+
+        The name of the URLConf keyword argument that contains the primary key.
+        By default, ``pk_url_kwarg`` is ``'pk'``.
+
     .. attribute:: context_object_name
 
         Designates the name of the variable to use in the context.
@@ -146,10 +156,11 @@ SingleObjectMixin
         ``queryset`` is provided, that queryset will be used as the
         source of objects; otherwise,
         :meth:`~SingleObjectMixin.get_queryset` will be used.
-        :meth:`~SingleObjectMixin.get_object` looks for a ``pk``
-        argument in the arguments to the view; if ``pk`` is found,
-        this method performs a primary-key based lookup using that
-        value. If no ``pk`` argument is found, it looks for a ``slug``
+        ``get_object()`` looks for a
+        :attr:`SingleObjectMixin.pk_url_kwarg` argument in the arguments
+        to the view; if this argument is found, this method performs a
+        primary-key based lookup using that value. If this argument is not
+        found, it looks for a :attr:`SingleObjectMixin.slug_url_kwarg`
         argument, and performs a slug lookup using the
         :attr:`SingleObjectMixin.slug_field`.
 
diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt
index ddbcda9..ae49150 100644
--- a/docs/releases/1.4.txt
+++ b/docs/releases/1.4.txt
@@ -106,6 +106,16 @@ A new helper function,
 ``template.Library`` to ease the creation of template tags that store some
 data in a specified context variable.
 
+Customizable ``SingleObjectMixin`` URLConf kwargs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two new attributes,
+:attr:`pk_url_kwarg<django.views.generic.detail.SingleObjectMixin.pk_url_kwarg>` and
+:attr:`slug_url_kwarg<django.views.generic.detail.SingleObjectMixin.slug_url_kwarg>`,
+have been added to :class:`django.views.generic.detail.SingleObjectMixin` to
+enable the customization of URLConf keyword arguments used for single
+object generic views.
+
 CSRF improvements
 ~~~~~~~~~~~~~~~~~
 
diff --git a/tests/regressiontests/generic_views/detail.py b/tests/regressiontests/generic_views/detail.py
index e8f2050..c1cc2fb 100644
--- a/tests/regressiontests/generic_views/detail.py
+++ b/tests/regressiontests/generic_views/detail.py
@@ -21,6 +21,13 @@ class DetailViewTest(TestCase):
         self.assertEqual(res.context['author'], Author.objects.get(pk=1))
         self.assertTemplateUsed(res, 'generic_views/author_detail.html')
 
+    def test_detail_by_custom_pk(self):
+        res = self.client.get('/detail/author/bycustompk/1/')
+        self.assertEqual(res.status_code, 200)
+        self.assertEqual(res.context['object'], Author.objects.get(pk=1))
+        self.assertEqual(res.context['author'], Author.objects.get(pk=1))
+        self.assertTemplateUsed(res, 'generic_views/author_detail.html')
+
     def test_detail_by_slug(self):
         res = self.client.get('/detail/author/byslug/scott-rosenberg/')
         self.assertEqual(res.status_code, 200)
@@ -28,6 +35,13 @@ class DetailViewTest(TestCase):
         self.assertEqual(res.context['author'], Author.objects.get(slug='scott-rosenberg'))
         self.assertTemplateUsed(res, 'generic_views/author_detail.html')
 
+    def test_detail_by_custom_slug(self):
+        res = self.client.get('/detail/author/bycustomslug/scott-rosenberg/')
+        self.assertEqual(res.status_code, 200)
+        self.assertEqual(res.context['object'], Author.objects.get(slug='scott-rosenberg'))
+        self.assertEqual(res.context['author'], Author.objects.get(slug='scott-rosenberg'))
+        self.assertTemplateUsed(res, 'generic_views/author_detail.html')
+
     def test_verbose_name(self):
         res = self.client.get('/detail/artist/1/')
         self.assertEqual(res.status_code, 200)
diff --git a/tests/regressiontests/generic_views/urls.py b/tests/regressiontests/generic_views/urls.py
index 067c1f6..0f844e0 100644
--- a/tests/regressiontests/generic_views/urls.py
+++ b/tests/regressiontests/generic_views/urls.py
@@ -30,8 +30,12 @@ urlpatterns = patterns('',
     url(r'^detail/author/(?P<pk>\d+)/$',
         views.AuthorDetail.as_view(),
         name="author_detail"),
+    (r'^detail/author/bycustompk/(?P<foo>\d+)/$',
+        views.AuthorDetail.as_view(pk_url_kwarg='foo')),
     (r'^detail/author/byslug/(?P<slug>[\w-]+)/$',
         views.AuthorDetail.as_view()),
+    (r'^detail/author/bycustomslug/(?P<foo>[\w-]+)/$',
+        views.AuthorDetail.as_view(slug_url_kwarg='foo')),
     (r'^detail/author/(?P<pk>\d+)/template_name_suffix/$',
         views.AuthorDetail.as_view(template_name_suffix='_view')),
     (r'^detail/author/(?P<pk>\d+)/template_name/$',
