Skip to content

Commit

Permalink
Fixed #3511 -- Changed QuerySet.get() to return a MultipleObjectsRetu…
Browse files Browse the repository at this point in the history
…rned exception, rather than an assertion error. Thanks, Gary Wilson and cheeming.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6838 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Dec 2, 2007
1 parent 5e5768a commit 805c364
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 6 deletions.
4 changes: 4 additions & 0 deletions django/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ class ObjectDoesNotExist(Exception):
"The requested object does not exist"
silent_variable_failure = True

class MultipleObjectsReturned(Exception):
"The query returned multiple objects when only one was expected."
pass

class SuspiciousOperation(Exception):
"The user did something suspicious"
pass
Expand Down
4 changes: 3 additions & 1 deletion django/db/models/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import django.db.models.manipulators
import django.db.models.manager
from django.core import validators
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
from django.db.models.fields.related import OneToOneRel, ManyToOneRel
from django.db.models.query import delete_objects
Expand Down Expand Up @@ -35,6 +35,8 @@ def __new__(cls, name, bases, attrs):
new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')})
new_class.add_to_class('_meta', Options(attrs.pop('Meta', None)))
new_class.add_to_class('DoesNotExist', types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {}))
new_class.add_to_class('MultipleObjectsReturned',
types.ClassType('MultipleObjectsReturned', (MultipleObjectsReturned, ), {}))

# Build complete list of parents
for base in bases:
Expand Down
3 changes: 2 additions & 1 deletion django/db/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ def get(self, *args, **kwargs):
obj_list = list(clone)
if len(obj_list) < 1:
raise self.model.DoesNotExist, "%s matching query does not exist." % self.model._meta.object_name
assert len(obj_list) == 1, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs)
elif len(obj_list) > 1:
raise self.model.MultipleObjectsReturned, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs)
return obj_list[0]

def create(self, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion django/shortcuts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get_object_or_404(klass, *args, **kwargs):
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the get() query.
Note: Like with get(), an AssertionError will be raised if more than one
Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
object is found.
"""
queryset = _get_queryset(klass)
Expand Down
4 changes: 2 additions & 2 deletions docs/shortcuts.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ This example is equivalent to::
except MyModel.DoesNotExist:
raise Http404

Note: As with ``get()``, an ``AssertionError`` will be raised if more than
one object is found.
Note: As with ``get()``, an ``MultipleObjectsReturned`` exception will be
raised if more than one object is found.

.. _get(): ../db-api/#get-kwargs

Expand Down
2 changes: 1 addition & 1 deletion tests/modeltests/get_object_or_404/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __unicode__(self):
>>> get_object_or_404(Author.objects.all())
Traceback (most recent call last):
...
AssertionError: get() returned more than one Author -- it returned ...! Lookup parameters were {}
MultipleObjectsReturned: get() returned more than one Author -- it returned ...! Lookup parameters were {}
# Using an EmptyQuerySet raises a Http404 error.
>>> get_object_or_404(Article.objects.none(), title__contains="Run")
Expand Down

0 comments on commit 805c364

Please sign in to comment.