Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #12152. DoesNotExist and MultipleObjectsReturned now subclass t…

…heir parent model's exceptions. Thanks, mattmcc and Alex Gaynor.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12567 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 1089bda54600b55a73f09c53c9b6dcee2f197b17 1 parent de1ff3e
Joseph Kocherhans authored February 24, 2010
20  django/db/models/base.py
@@ -52,10 +52,14 @@ def __new__(cls, name, bases, attrs):
52 52
 
53 53
         new_class.add_to_class('_meta', Options(meta, **kwargs))
54 54
         if not abstract:
55  
-            new_class.add_to_class('DoesNotExist',
56  
-                    subclass_exception('DoesNotExist', ObjectDoesNotExist, module))
57  
-            new_class.add_to_class('MultipleObjectsReturned',
58  
-                    subclass_exception('MultipleObjectsReturned', MultipleObjectsReturned, module))
  55
+            new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
  56
+                    tuple(x.DoesNotExist
  57
+                            for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
  58
+                                    or (ObjectDoesNotExist,), module))
  59
+            new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
  60
+                    tuple(x.MultipleObjectsReturned
  61
+                            for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
  62
+                                    or (MultipleObjectsReturned,), module))
59 63
             if base_meta and not base_meta.abstract:
60 64
                 # Non-abstract child classes inherit some attributes from their
61 65
                 # non-abstract parent (unless an ABC comes before it in the
@@ -919,8 +923,8 @@ def model_unpickle(model, attrs, factory):
919 923
 
920 924
 if sys.version_info < (2, 5):
921 925
     # Prior to Python 2.5, Exception was an old-style class
922  
-    def subclass_exception(name, parent, unused):
923  
-        return types.ClassType(name, (parent,), {})
  926
+    def subclass_exception(name, parents, unused):
  927
+        return types.ClassType(name, parents, {})
924 928
 else:
925  
-    def subclass_exception(name, parent, module):
926  
-        return type(name, (parent,), {'__module__': module})
  929
+    def subclass_exception(name, parents, module):
  930
+        return type(name, parents, {'__module__': module})
41  tests/modeltests/model_inheritance/models.py
@@ -38,6 +38,9 @@ class Student(CommonInfo):
38 38
     class Meta:
39 39
         pass
40 40
 
  41
+class StudentWorker(Student, Worker):
  42
+    pass
  43
+
41 44
 #
42 45
 # Abstract base classes with related models
43 46
 #
@@ -176,6 +179,32 @@ def __unicode__(self):
176 179
     ...
177 180
 AttributeError: type object 'CommonInfo' has no attribute 'objects'
178 181
 
  182
+# A StudentWorker which does not exist is both a Student and Worker which does not exist.
  183
+>>> try:
  184
+...     StudentWorker.objects.get(id=1)
  185
+... except Student.DoesNotExist:
  186
+...     pass
  187
+>>> try:
  188
+...     StudentWorker.objects.get(id=1)
  189
+... except Worker.DoesNotExist:
  190
+...     pass
  191
+
  192
+# MultipleObjectsReturned is also inherited.
  193
+>>> sw1 = StudentWorker()
  194
+>>> sw1.name = 'Wilma'
  195
+>>> sw1.age = 35
  196
+>>> sw1.save()
  197
+>>> sw2 = StudentWorker()
  198
+>>> sw2.name = 'Betty'
  199
+>>> sw2.age = 34
  200
+>>> sw2.save()
  201
+>>> try:
  202
+...     StudentWorker.objects.get(id__lt=10)
  203
+... except Student.MultipleObjectsReturned:
  204
+...     pass
  205
+... except Worker.MultipleObjectsReturned:
  206
+...     pass
  207
+
179 208
 # Create a Post
180 209
 >>> post = Post(title='Lorem Ipsum')
181 210
 >>> post.save()
@@ -267,6 +296,18 @@ def __unicode__(self):
267 296
     ...
268 297
 DoesNotExist: ItalianRestaurant matching query does not exist.
269 298
 
  299
+# An ItalianRestaurant which does not exist is also a Place which does not exist.
  300
+>>> try:
  301
+...     ItalianRestaurant.objects.get(name='The Noodle Void')
  302
+... except Place.DoesNotExist:
  303
+...     pass
  304
+
  305
+# MultipleObjectsReturned is also inherited.
  306
+>>> try:
  307
+...     Restaurant.objects.get(id__lt=10)
  308
+... except Place.MultipleObjectsReturned:
  309
+...     pass
  310
+
270 311
 # Related objects work just as they normally do.
271 312
 
272 313
 >>> s1 = Supplier(name="Joe's Chickens", address='123 Sesame St')
20  tests/modeltests/proxy_models/models.py
@@ -206,6 +206,26 @@ class Meta:
206 206
 >>> MyPersonProxy.objects.all()
207 207
 [<MyPersonProxy: Bazza del Frob>, <MyPersonProxy: Foo McBar>, <MyPersonProxy: homer>]
208 208
 
  209
+# Proxy models are included in the ancestors for a model's DoesNotExist and MultipleObjectsReturned
  210
+>>> try:
  211
+...     MyPersonProxy.objects.get(name='Zathras')
  212
+... except Person.DoesNotExist:
  213
+...     pass
  214
+>>> try:
  215
+...     MyPersonProxy.objects.get(id__lt=10)
  216
+... except Person.MultipleObjectsReturned:
  217
+...     pass
  218
+>>> try:
  219
+...     StatusPerson.objects.get(name='Zathras')
  220
+... except Person.DoesNotExist:
  221
+...     pass
  222
+>>> sp1 = StatusPerson.objects.create(name='Bazza Jr.')
  223
+>>> sp2 = StatusPerson.objects.create(name='Foo Jr.')
  224
+>>> try:
  225
+...     StatusPerson.objects.get(id__lt=10)
  226
+... except Person.MultipleObjectsReturned:
  227
+...     pass
  228
+
209 229
 # And now for some things that shouldn't work...
210 230
 #
211 231
 # All base classes must be non-abstract

0 notes on commit 1089bda

Please sign in to comment.
Something went wrong with that request. Please try again.