Fixed #21619 -- Made SingleObjectMixin.get_object catch a more precise exception.

Thanks to Keryn Knight for the report.
This commit is contained in:
Peter Harley 2013-12-14 23:15:35 +00:00 committed by Baptiste Mispelon
parent a1bc3683ff
commit cdd6617da6
5 changed files with 29 additions and 4 deletions

View File

@ -1,6 +1,6 @@
from __future__ import unicode_literals
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.http import Http404
from django.utils.translation import ugettext as _
@ -50,7 +50,7 @@ class SingleObjectMixin(ContextMixin):
try:
# Get the single item from the filtered queryset
obj = queryset.get()
except ObjectDoesNotExist:
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return obj

View File

@ -1,5 +1,7 @@
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import QuerySet
from django.db.models.manager import BaseManager
from django.utils.encoding import python_2_unicode_compatible
@ -31,6 +33,13 @@ class Author(models.Model):
return self.name
class DoesNotExistQuerySet(QuerySet):
def get(self, *args, **kwargs):
raise Author.DoesNotExist
DoesNotExistBookManager = BaseManager.from_queryset(DoesNotExistQuerySet)
@python_2_unicode_compatible
class Book(models.Model):
name = models.CharField(max_length=300)
@ -39,6 +48,9 @@ class Book(models.Model):
authors = models.ManyToManyField(Author)
pubdate = models.DateField()
objects = models.Manager()
does_not_exist = DoesNotExistBookManager()
class Meta:
ordering = ['-pubdate']

View File

@ -1,6 +1,6 @@
from __future__ import unicode_literals
from django.core.exceptions import ImproperlyConfigured
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.test import TestCase
from django.views.generic.base import View
@ -25,6 +25,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_missing_object(self):
res = self.client.get('/detail/author/500/')
self.assertEqual(res.status_code, 404)
def test_detail_object_does_not_exist(self):
self.assertRaises(ObjectDoesNotExist, self.client.get, '/detail/doesnotexist/1/')
def test_detail_by_custom_pk(self):
res = self.client.get('/detail/author/bycustompk/1/')
self.assertEqual(res.status_code, 200)

View File

@ -55,7 +55,8 @@ urlpatterns = patterns('',
views.AuthorDetail.as_view(queryset=None)),
(r'^detail/nonmodel/1/$',
views.NonModelDetail.as_view()),
(r'^detail/doesnotexist/(?P<pk>\d+)/$',
views.ObjectDoesNotExistDetail.as_view()),
# FormView
(r'^contact/$',
views.ContactView.as_view()),

View File

@ -300,3 +300,8 @@ class NonModelDetail(generic.DetailView):
def get_object(self, queryset=None):
return NonModel()
class ObjectDoesNotExistDetail(generic.DetailView):
def get_queryset(self):
return Book.does_not_exist.all()