summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2010-02-24 14:42:03 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2010-02-24 14:42:03 +0000
commit18c800f1a389e20de45e0df0f8de3fa5303f887d (patch)
treea9d07238742bcc145c732035a58049504ca2d4bf
parentfbe455e1ac7a05032aaa28a89c79d7f1cafc33b7 (diff)
[1.1.X] Fixed #12152. DoesNotExist and MultipleObjectsReturned now subclass their parent model's exceptions. Backport of r12567 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@12568 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/models/base.py20
-rw-r--r--tests/modeltests/model_inheritance/models.py41
-rw-r--r--tests/modeltests/proxy_models/models.py20
3 files changed, 73 insertions, 8 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index d952327d01..ad80a863cb 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -55,10 +55,14 @@ class ModelBase(type):
new_class.add_to_class('_meta', Options(meta, **kwargs))
if not abstract:
- new_class.add_to_class('DoesNotExist',
- subclass_exception('DoesNotExist', ObjectDoesNotExist, module))
- new_class.add_to_class('MultipleObjectsReturned',
- subclass_exception('MultipleObjectsReturned', MultipleObjectsReturned, module))
+ new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
+ tuple(x.DoesNotExist
+ for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
+ or (ObjectDoesNotExist,), module))
+ new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
+ tuple(x.MultipleObjectsReturned
+ for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
+ or (MultipleObjectsReturned,), module))
if base_meta and not base_meta.abstract:
# Non-abstract child classes inherit some attributes from their
# non-abstract parent (unless an ABC comes before it in the
@@ -681,8 +685,8 @@ model_unpickle.__safe_for_unpickle__ = True
if sys.version_info < (2, 5):
# Prior to Python 2.5, Exception was an old-style class
- def subclass_exception(name, parent, unused):
- return types.ClassType(name, (parent,), {})
+ def subclass_exception(name, parents, unused):
+ return types.ClassType(name, parents, {})
else:
- def subclass_exception(name, parent, module):
- return type(name, (parent,), {'__module__': module})
+ def subclass_exception(name, parents, module):
+ return type(name, parents, {'__module__': module})
diff --git a/tests/modeltests/model_inheritance/models.py b/tests/modeltests/model_inheritance/models.py
index 26ec0be503..37a1ca0c28 100644
--- a/tests/modeltests/model_inheritance/models.py
+++ b/tests/modeltests/model_inheritance/models.py
@@ -38,6 +38,9 @@ class Student(CommonInfo):
class Meta:
pass
+class StudentWorker(Student, Worker):
+ pass
+
#
# Abstract base classes with related models
#
@@ -151,6 +154,32 @@ Traceback (most recent call last):
...
AttributeError: type object 'CommonInfo' has no attribute 'objects'
+# A StudentWorker which does not exist is both a Student and Worker which does not exist.
+>>> try:
+... StudentWorker.objects.get(id=1)
+... except Student.DoesNotExist:
+... pass
+>>> try:
+... StudentWorker.objects.get(id=1)
+... except Worker.DoesNotExist:
+... pass
+
+# MultipleObjectsReturned is also inherited.
+>>> sw1 = StudentWorker()
+>>> sw1.name = 'Wilma'
+>>> sw1.age = 35
+>>> sw1.save()
+>>> sw2 = StudentWorker()
+>>> sw2.name = 'Betty'
+>>> sw2.age = 34
+>>> sw2.save()
+>>> try:
+... StudentWorker.objects.get(id__lt=10)
+... except Student.MultipleObjectsReturned:
+... pass
+... except Worker.MultipleObjectsReturned:
+... pass
+
# Create a Post
>>> post = Post(title='Lorem Ipsum')
>>> post.save()
@@ -242,6 +271,18 @@ Traceback (most recent call last):
...
DoesNotExist: ItalianRestaurant matching query does not exist.
+# An ItalianRestaurant which does not exist is also a Place which does not exist.
+>>> try:
+... ItalianRestaurant.objects.get(name='The Noodle Void')
+... except Place.DoesNotExist:
+... pass
+
+# MultipleObjectsReturned is also inherited.
+>>> try:
+... Restaurant.objects.get(id__lt=10)
+... except Place.MultipleObjectsReturned:
+... pass
+
# Related objects work just as they normally do.
>>> s1 = Supplier(name="Joe's Chickens", address='123 Sesame St')
diff --git a/tests/modeltests/proxy_models/models.py b/tests/modeltests/proxy_models/models.py
index e38266fb70..5621e6d692 100644
--- a/tests/modeltests/proxy_models/models.py
+++ b/tests/modeltests/proxy_models/models.py
@@ -205,6 +205,26 @@ False
>>> MyPersonProxy.objects.all()
[<MyPersonProxy: Bazza del Frob>, <MyPersonProxy: Foo McBar>, <MyPersonProxy: homer>]
+# Proxy models are included in the ancestors for a model's DoesNotExist and MultipleObjectsReturned
+>>> try:
+... MyPersonProxy.objects.get(name='Zathras')
+... except Person.DoesNotExist:
+... pass
+>>> try:
+... MyPersonProxy.objects.get(id__lt=10)
+... except Person.MultipleObjectsReturned:
+... pass
+>>> try:
+... StatusPerson.objects.get(name='Zathras')
+... except Person.DoesNotExist:
+... pass
+>>> sp1 = StatusPerson.objects.create(name='Bazza Jr.')
+>>> sp2 = StatusPerson.objects.create(name='Foo Jr.')
+>>> try:
+... StatusPerson.objects.get(id__lt=10)
+... except Person.MultipleObjectsReturned:
+... pass
+
# And now for some things that shouldn't work...
#
# All base classes must be non-abstract