Fixed #19432 -- Provided better error message for get_object_or_404
Thanks Kit Sunde for the report and Brian Holdefehr for the initial patch.
This commit is contained in:
parent
6cad5f212a
commit
6ed6a18a03
|
@ -7,6 +7,7 @@ for convenience's sake.
|
||||||
from django.template import loader, RequestContext
|
from django.template import loader, RequestContext
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
|
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
|
||||||
|
from django.db.models.base import ModelBase
|
||||||
from django.db.models.manager import Manager
|
from django.db.models.manager import Manager
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.core import urlresolvers
|
from django.core import urlresolvers
|
||||||
|
@ -72,13 +73,20 @@ def _get_queryset(klass):
|
||||||
"""
|
"""
|
||||||
Returns a QuerySet from a Model, Manager, or QuerySet. Created to make
|
Returns a QuerySet from a Model, Manager, or QuerySet. Created to make
|
||||||
get_object_or_404 and get_list_or_404 more DRY.
|
get_object_or_404 and get_list_or_404 more DRY.
|
||||||
|
|
||||||
|
Raises a ValueError if klass is not a Model, Manager, or QuerySet.
|
||||||
"""
|
"""
|
||||||
if isinstance(klass, QuerySet):
|
if isinstance(klass, QuerySet):
|
||||||
return klass
|
return klass
|
||||||
elif isinstance(klass, Manager):
|
elif isinstance(klass, Manager):
|
||||||
manager = klass
|
manager = klass
|
||||||
else:
|
elif isinstance(klass, ModelBase):
|
||||||
manager = klass._default_manager
|
manager = klass._default_manager
|
||||||
|
else:
|
||||||
|
klass__name = klass.__name__ if isinstance(klass, type) \
|
||||||
|
else klass.__class__.__name__
|
||||||
|
raise ValueError("Object is of type '%s', but must be a Django Model, "
|
||||||
|
"Manager, or QuerySet" % klass__name)
|
||||||
return manager.all()
|
return manager.all()
|
||||||
|
|
||||||
def get_object_or_404(klass, *args, **kwargs):
|
def get_object_or_404(klass, *args, **kwargs):
|
||||||
|
|
|
@ -80,3 +80,28 @@ class GetObjectOr404Tests(TestCase):
|
||||||
get_list_or_404(Article.objects.all(), title__icontains="Run"),
|
get_list_or_404(Article.objects.all(), title__icontains="Run"),
|
||||||
[article]
|
[article]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_bad_class(self):
|
||||||
|
# Given an argument klass that is not a Model, Manager, or Queryset
|
||||||
|
# raises a helpful ValueError message
|
||||||
|
self.assertRaisesMessage(ValueError,
|
||||||
|
"Object is of type 'str', but must be a Django Model, Manager, "
|
||||||
|
"or QuerySet",
|
||||||
|
get_object_or_404, "Article", title__icontains="Run"
|
||||||
|
)
|
||||||
|
|
||||||
|
class CustomClass(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertRaisesMessage(ValueError,
|
||||||
|
"Object is of type 'CustomClass', but must be a Django Model, "
|
||||||
|
"Manager, or QuerySet",
|
||||||
|
get_object_or_404, CustomClass, title__icontains="Run"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Works for lists too
|
||||||
|
self.assertRaisesMessage(ValueError,
|
||||||
|
"Object is of type 'list', but must be a Django Model, Manager, "
|
||||||
|
"or QuerySet",
|
||||||
|
get_list_or_404, [Article], title__icontains="Run"
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue