Fixed #16101 -- Added parameters to SingleObjectMixin to override the name of the URL keyword arguments used for pk and slug. Thanks, Andrew Ingram and Julien Phalip.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16569 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-07-29 09:41:00 +00:00
parent 5fffe574bd
commit 2ccfb6d5c2
5 changed files with 51 additions and 6 deletions

View File

@ -13,6 +13,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):
"""
@ -27,8 +29,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)

View File

@ -136,6 +136,20 @@ SingleObjectMixin
The name of the field on the model that contains the slug. By default,
``slug_field`` is ``'slug'``.
.. attribute:: slug_url_kwarg
.. versionadded:: 1.4
The name of the URLConf keyword argument that contains the slug. By
default, ``slug_url_kwarg`` is ``'slug'``.
.. attribute:: pk_url_kwarg
.. versionadded:: 1.4
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 +160,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`.

View File

@ -153,6 +153,16 @@ number of characters. Truncated strings end with a translatable ellipsis
sequence ("..."). See the :tfilter:`truncatechars docs <truncatechars>` for
more details.
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
~~~~~~~~~~~~~~~~~

View File

@ -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)

View File

@ -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/$',