Skip to content

Commit 18c800f

Browse files
committed
[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
1 parent fbe455e commit 18c800f

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

django/db/models/base.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@ def __new__(cls, name, bases, attrs):
5555

5656
new_class.add_to_class('_meta', Options(meta, **kwargs))
5757
if not abstract:
58-
new_class.add_to_class('DoesNotExist',
59-
subclass_exception('DoesNotExist', ObjectDoesNotExist, module))
60-
new_class.add_to_class('MultipleObjectsReturned',
61-
subclass_exception('MultipleObjectsReturned', MultipleObjectsReturned, module))
58+
new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
59+
tuple(x.DoesNotExist
60+
for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
61+
or (ObjectDoesNotExist,), module))
62+
new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
63+
tuple(x.MultipleObjectsReturned
64+
for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
65+
or (MultipleObjectsReturned,), module))
6266
if base_meta and not base_meta.abstract:
6367
# Non-abstract child classes inherit some attributes from their
6468
# non-abstract parent (unless an ABC comes before it in the
@@ -681,8 +685,8 @@ def model_unpickle(model, attrs, factory):
681685

682686
if sys.version_info < (2, 5):
683687
# Prior to Python 2.5, Exception was an old-style class
684-
def subclass_exception(name, parent, unused):
685-
return types.ClassType(name, (parent,), {})
688+
def subclass_exception(name, parents, unused):
689+
return types.ClassType(name, parents, {})
686690
else:
687-
def subclass_exception(name, parent, module):
688-
return type(name, (parent,), {'__module__': module})
691+
def subclass_exception(name, parents, module):
692+
return type(name, parents, {'__module__': module})

tests/modeltests/model_inheritance/models.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class Student(CommonInfo):
3838
class Meta:
3939
pass
4040

41+
class StudentWorker(Student, Worker):
42+
pass
43+
4144
#
4245
# Abstract base classes with related models
4346
#
@@ -151,6 +154,32 @@ def __unicode__(self):
151154
...
152155
AttributeError: type object 'CommonInfo' has no attribute 'objects'
153156
157+
# A StudentWorker which does not exist is both a Student and Worker which does not exist.
158+
>>> try:
159+
... StudentWorker.objects.get(id=1)
160+
... except Student.DoesNotExist:
161+
... pass
162+
>>> try:
163+
... StudentWorker.objects.get(id=1)
164+
... except Worker.DoesNotExist:
165+
... pass
166+
167+
# MultipleObjectsReturned is also inherited.
168+
>>> sw1 = StudentWorker()
169+
>>> sw1.name = 'Wilma'
170+
>>> sw1.age = 35
171+
>>> sw1.save()
172+
>>> sw2 = StudentWorker()
173+
>>> sw2.name = 'Betty'
174+
>>> sw2.age = 34
175+
>>> sw2.save()
176+
>>> try:
177+
... StudentWorker.objects.get(id__lt=10)
178+
... except Student.MultipleObjectsReturned:
179+
... pass
180+
... except Worker.MultipleObjectsReturned:
181+
... pass
182+
154183
# Create a Post
155184
>>> post = Post(title='Lorem Ipsum')
156185
>>> post.save()
@@ -242,6 +271,18 @@ def __unicode__(self):
242271
...
243272
DoesNotExist: ItalianRestaurant matching query does not exist.
244273
274+
# An ItalianRestaurant which does not exist is also a Place which does not exist.
275+
>>> try:
276+
... ItalianRestaurant.objects.get(name='The Noodle Void')
277+
... except Place.DoesNotExist:
278+
... pass
279+
280+
# MultipleObjectsReturned is also inherited.
281+
>>> try:
282+
... Restaurant.objects.get(id__lt=10)
283+
... except Place.MultipleObjectsReturned:
284+
... pass
285+
245286
# Related objects work just as they normally do.
246287
247288
>>> s1 = Supplier(name="Joe's Chickens", address='123 Sesame St')

tests/modeltests/proxy_models/models.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,26 @@ class Meta:
205205
>>> MyPersonProxy.objects.all()
206206
[<MyPersonProxy: Bazza del Frob>, <MyPersonProxy: Foo McBar>, <MyPersonProxy: homer>]
207207
208+
# Proxy models are included in the ancestors for a model's DoesNotExist and MultipleObjectsReturned
209+
>>> try:
210+
... MyPersonProxy.objects.get(name='Zathras')
211+
... except Person.DoesNotExist:
212+
... pass
213+
>>> try:
214+
... MyPersonProxy.objects.get(id__lt=10)
215+
... except Person.MultipleObjectsReturned:
216+
... pass
217+
>>> try:
218+
... StatusPerson.objects.get(name='Zathras')
219+
... except Person.DoesNotExist:
220+
... pass
221+
>>> sp1 = StatusPerson.objects.create(name='Bazza Jr.')
222+
>>> sp2 = StatusPerson.objects.create(name='Foo Jr.')
223+
>>> try:
224+
... StatusPerson.objects.get(id__lt=10)
225+
... except Person.MultipleObjectsReturned:
226+
... pass
227+
208228
# And now for some things that shouldn't work...
209229
#
210230
# All base classes must be non-abstract

0 commit comments

Comments
 (0)