Fixed #29135 -- Prevented get_object/list_or_404() from hiding AttributeError raised by QuerySet filtering.
This commit is contained in:
parent
9b1125bfc7
commit
eb002e7892
|
@ -83,14 +83,14 @@ def get_object_or_404(klass, *args, **kwargs):
|
||||||
one object is found.
|
one object is found.
|
||||||
"""
|
"""
|
||||||
queryset = _get_queryset(klass)
|
queryset = _get_queryset(klass)
|
||||||
try:
|
if not hasattr(queryset, 'get'):
|
||||||
return queryset.get(*args, **kwargs)
|
|
||||||
except AttributeError:
|
|
||||||
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
|
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"First argument to get_object_or_404() must be a Model, Manager, "
|
"First argument to get_object_or_404() must be a Model, Manager, "
|
||||||
"or QuerySet, not '%s'." % klass__name
|
"or QuerySet, not '%s'." % klass__name
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
return queryset.get(*args, **kwargs)
|
||||||
except queryset.model.DoesNotExist:
|
except queryset.model.DoesNotExist:
|
||||||
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
|
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
|
||||||
|
|
||||||
|
@ -104,14 +104,13 @@ def get_list_or_404(klass, *args, **kwargs):
|
||||||
arguments and keyword arguments are used in the filter() query.
|
arguments and keyword arguments are used in the filter() query.
|
||||||
"""
|
"""
|
||||||
queryset = _get_queryset(klass)
|
queryset = _get_queryset(klass)
|
||||||
try:
|
if not hasattr(queryset, 'filter'):
|
||||||
obj_list = list(queryset.filter(*args, **kwargs))
|
|
||||||
except AttributeError:
|
|
||||||
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
|
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"First argument to get_list_or_404() must be a Model, Manager, or "
|
"First argument to get_list_or_404() must be a Model, Manager, or "
|
||||||
"QuerySet, not '%s'." % klass__name
|
"QuerySet, not '%s'." % klass__name
|
||||||
)
|
)
|
||||||
|
obj_list = list(queryset.filter(*args, **kwargs))
|
||||||
if not obj_list:
|
if not obj_list:
|
||||||
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
|
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
|
||||||
return obj_list
|
return obj_list
|
||||||
|
|
|
@ -25,11 +25,17 @@ class ArticleManager(models.Manager):
|
||||||
return super().get_queryset().filter(authors__name__icontains='sir')
|
return super().get_queryset().filter(authors__name__icontains='sir')
|
||||||
|
|
||||||
|
|
||||||
|
class AttributeErrorManager(models.Manager):
|
||||||
|
def get_queryset(self):
|
||||||
|
raise AttributeError('AttributeErrorManager')
|
||||||
|
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
authors = models.ManyToManyField(Author)
|
authors = models.ManyToManyField(Author)
|
||||||
title = models.CharField(max_length=50)
|
title = models.CharField(max_length=50)
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
by_a_sir = ArticleManager()
|
by_a_sir = ArticleManager()
|
||||||
|
attribute_error_objects = AttributeErrorManager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
|
@ -94,3 +94,13 @@ class GetObjectOr404Tests(TestCase):
|
||||||
msg = "First argument to get_list_or_404() must be a Model, Manager, or QuerySet, not 'list'."
|
msg = "First argument to get_list_or_404() must be a Model, Manager, or QuerySet, not 'list'."
|
||||||
with self.assertRaisesMessage(ValueError, msg):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
get_list_or_404([Article], title__icontains="Run")
|
get_list_or_404([Article], title__icontains="Run")
|
||||||
|
|
||||||
|
def test_get_object_or_404_queryset_attribute_error(self):
|
||||||
|
"""AttributeError raised by QuerySet.get() isn't hidden."""
|
||||||
|
with self.assertRaisesMessage(AttributeError, 'AttributeErrorManager'):
|
||||||
|
get_object_or_404(Article.attribute_error_objects, id=42)
|
||||||
|
|
||||||
|
def test_get_list_or_404_queryset_attribute_error(self):
|
||||||
|
"""AttributeError raised by QuerySet.filter() isn't hidden."""
|
||||||
|
with self.assertRaisesMessage(AttributeError, 'AttributeErrorManager'):
|
||||||
|
get_list_or_404(Article.attribute_error_objects, title__icontains='Run')
|
||||||
|
|
Loading…
Reference in New Issue