Fixed #21619 -- Made SingleObjectMixin.get_object catch a more precise exception.
Thanks to Keryn Knight for the report.
This commit is contained in:
parent
a1bc3683ff
commit
cdd6617da6
|
@ -1,6 +1,6 @@
|
||||||
from __future__ import unicode_literals
|
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.db import models
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
@ -50,7 +50,7 @@ class SingleObjectMixin(ContextMixin):
|
||||||
try:
|
try:
|
||||||
# Get the single item from the filtered queryset
|
# Get the single item from the filtered queryset
|
||||||
obj = queryset.get()
|
obj = queryset.get()
|
||||||
except ObjectDoesNotExist:
|
except queryset.model.DoesNotExist:
|
||||||
raise Http404(_("No %(verbose_name)s found matching the query") %
|
raise Http404(_("No %(verbose_name)s found matching the query") %
|
||||||
{'verbose_name': queryset.model._meta.verbose_name})
|
{'verbose_name': queryset.model._meta.verbose_name})
|
||||||
return obj
|
return obj
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import models
|
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
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +33,13 @@ class Author(models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class DoesNotExistQuerySet(QuerySet):
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
raise Author.DoesNotExist
|
||||||
|
|
||||||
|
DoesNotExistBookManager = BaseManager.from_queryset(DoesNotExistQuerySet)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Book(models.Model):
|
class Book(models.Model):
|
||||||
name = models.CharField(max_length=300)
|
name = models.CharField(max_length=300)
|
||||||
|
@ -39,6 +48,9 @@ class Book(models.Model):
|
||||||
authors = models.ManyToManyField(Author)
|
authors = models.ManyToManyField(Author)
|
||||||
pubdate = models.DateField()
|
pubdate = models.DateField()
|
||||||
|
|
||||||
|
objects = models.Manager()
|
||||||
|
does_not_exist = DoesNotExistBookManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['-pubdate']
|
ordering = ['-pubdate']
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from __future__ import unicode_literals
|
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.test import TestCase
|
||||||
from django.views.generic.base import View
|
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.assertEqual(res.context['author'], Author.objects.get(pk=1))
|
||||||
self.assertTemplateUsed(res, 'generic_views/author_detail.html')
|
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):
|
def test_detail_by_custom_pk(self):
|
||||||
res = self.client.get('/detail/author/bycustompk/1/')
|
res = self.client.get('/detail/author/bycustompk/1/')
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
|
|
|
@ -55,7 +55,8 @@ urlpatterns = patterns('',
|
||||||
views.AuthorDetail.as_view(queryset=None)),
|
views.AuthorDetail.as_view(queryset=None)),
|
||||||
(r'^detail/nonmodel/1/$',
|
(r'^detail/nonmodel/1/$',
|
||||||
views.NonModelDetail.as_view()),
|
views.NonModelDetail.as_view()),
|
||||||
|
(r'^detail/doesnotexist/(?P<pk>\d+)/$',
|
||||||
|
views.ObjectDoesNotExistDetail.as_view()),
|
||||||
# FormView
|
# FormView
|
||||||
(r'^contact/$',
|
(r'^contact/$',
|
||||||
views.ContactView.as_view()),
|
views.ContactView.as_view()),
|
||||||
|
|
|
@ -300,3 +300,8 @@ class NonModelDetail(generic.DetailView):
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
return NonModel()
|
return NonModel()
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectDoesNotExistDetail(generic.DetailView):
|
||||||
|
def get_queryset(self):
|
||||||
|
return Book.does_not_exist.all()
|
||||||
|
|
Loading…
Reference in New Issue