summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2012-12-12 20:34:59 +0100
committerClaude Paroz <claude@2xlibre.net>2012-12-12 22:05:49 +0100
commitc20c3a20a313b24df6d115e585c04c8dc60d3970 (patch)
tree0de20b00afafcf51d24a0ba9fb1c12b78bbffe20
parent8a1b4dbda207d8c790b5801d62e7ff3df65a79df (diff)
[1.5.x] Fixed #19432 -- Provided better error message for get_object_or_404
Thanks Kit Sunde for the report and Brian Holdefehr for the initial patch. Backport of 6ed6a18a0 from master.
-rw-r--r--django/shortcuts/__init__.py10
-rw-r--r--tests/modeltests/get_object_or_404/tests.py25
2 files changed, 34 insertions, 1 deletions
diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
index a824446b7e..9ddbdef8d6 100644
--- a/django/shortcuts/__init__.py
+++ b/django/shortcuts/__init__.py
@@ -7,6 +7,7 @@ for convenience's sake.
from django.template import loader, RequestContext
from django.http import HttpResponse, Http404
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
+from django.db.models.base import ModelBase
from django.db.models.manager import Manager
from django.db.models.query import QuerySet
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
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):
return klass
elif isinstance(klass, Manager):
manager = klass
- else:
+ elif isinstance(klass, ModelBase):
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()
def get_object_or_404(klass, *args, **kwargs):
diff --git a/tests/modeltests/get_object_or_404/tests.py b/tests/modeltests/get_object_or_404/tests.py
index 280720fd15..3b234c6cd3 100644
--- a/tests/modeltests/get_object_or_404/tests.py
+++ b/tests/modeltests/get_object_or_404/tests.py
@@ -80,3 +80,28 @@ class GetObjectOr404Tests(TestCase):
get_list_or_404(Article.objects.all(), title__icontains="Run"),
[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"
+ )