Ticket #12152: 12152-1.diff

File 12152-1.diff, 6.2 KB (added by mattmcc, 6 years ago)
  • django/db/models/base.py

     
    4949
    5050        new_class.add_to_class('_meta', Options(meta, **kwargs))
    5151        if not abstract:
    52             new_class.add_to_class('DoesNotExist',
    53                     subclass_exception('DoesNotExist', ObjectDoesNotExist, module))
    54             new_class.add_to_class('MultipleObjectsReturned',
    55                     subclass_exception('MultipleObjectsReturned', MultipleObjectsReturned, module))
    5652            if base_meta and not base_meta.abstract:
    5753                # Non-abstract child classes inherit some attributes from their
    5854                # non-abstract parent (unless an ABC comes before it in the
     
    118114        o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
    119115                if isinstance(f, OneToOneField)])
    120116
     117        exception_class_bases = []
    121118        for base in parents:
    122119            original_base = base
    123120            if not hasattr(base, '_meta'):
     
    136133                                     'base class %r' %
    137134                                        (field.name, name, base.__name__))
    138135            if not base._meta.abstract:
     136                exception_class_bases.append(base)
    139137                # Concrete classes...
    140138                while base._meta.proxy:
    141139                    # Skip over a proxy class to the "real" base it proxies.
     
    176174                                        (field.name, name, base.__name__))
    177175                new_class.add_to_class(field.name, copy.deepcopy(field))
    178176
     177        # If a model has non-abstract parent models, the model's inner
     178        # exception classes should inherit from theirs.
     179        if exception_class_bases:
     180            does_not_exist_parents = tuple(getattr(x, 'DoesNotExist')
     181                            for x in exception_class_bases)
     182            multiple_objects_returned_parents = tuple(getattr(x, 'MultipleObjectsReturned')
     183                            for x in exception_class_bases)
     184        else:
     185            does_not_exist_parents = ObjectDoesNotExist
     186            multiple_objects_returned_parents = MultipleObjectsReturned
     187        new_class.add_to_class('DoesNotExist',
     188                subclass_exception('DoesNotExist',
     189                        does_not_exist_parents, module))
     190        new_class.add_to_class('MultipleObjectsReturned',
     191                subclass_exception('MultipleObjectsReturned',
     192                        multiple_objects_returned_parents, module))
     193
    179194        if abstract:
    180195            # Abstract base models can't be instantiated and don't appear in
    181196            # the list of models for an app. We do the final setup for them a
     
    669684if sys.version_info < (2, 5):
    670685    # Prior to Python 2.5, Exception was an old-style class
    671686    def subclass_exception(name, parent, unused):
    672         return types.ClassType(name, (parent,), {})
     687        return types.ClassType(name,
     688                    (parent,) if type(parent) == type else parent, {})
    673689else:
    674690    def subclass_exception(name, parent, module):
    675         return type(name, (parent,), {'__module__': module})
     691        return type(name, (parent,) if type(parent) == type else parent,
     692                    {'__module__': module})
  • tests/modeltests/proxy_models/models.py

     
    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
  • tests/modeltests/model_inheritance/models.py

     
    3838    class Meta:
    3939        pass
    4040
     41class StudentWorker(Student, Worker):
     42    pass
     43
    4144#
    4245# Abstract base classes with related models
    4346#
     
    151154    ...
    152155AttributeError: 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()
     
    242271    ...
    243272DoesNotExist: 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')
Back to Top