Fixed #3511 -- Changed QuerySet.get() to return a MultipleObjectsReturned 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
This commit is contained in:
Malcolm Tredinnick 2007-12-02 18:21:07 +00:00
parent 5e5768ae83
commit 805c364fcf
6 changed files with 13 additions and 6 deletions

View File

@ -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

View File

@ -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
@ -35,6 +35,8 @@ class ModelBase(type):
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:

View File

@ -261,7 +261,8 @@ class _QuerySet(object):
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):

View File

@ -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)

View File

@ -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

View File

@ -78,7 +78,7 @@ Http404: No Article matches the given query.
>>> 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")