Ticket #15250: fill_parent_model_instance_1.diff

File fill_parent_model_instance_1.diff, 4.1 KB (added by marekw2143, 4 years ago)
  • db/models/base.py

     
    99from django.core import validators
    1010from django.db.models.fields import AutoField, FieldDoesNotExist
    1111from django.db.models.fields.related import (OneToOneRel, ManyToOneRel,
    12     OneToOneField, add_lazy_relation)
     12    OneToOneField, add_lazy_relation, ReverseSingleRelatedObjectDescriptorParent)
    1313from django.db.models.query import Q
    1414from django.db.models.query_utils import DeferredAttribute
    1515from django.db.models.deletion import Collector
     
    155155                elif not is_proxy:
    156156                    attr_name = '%s_ptr' % base._meta.module_name
    157157                    field = OneToOneField(base, name=attr_name,
    158                             auto_created=True, parent_link=True)
     158                            auto_created=True, rev_class = ReverseSingleRelatedObjectDescriptorParent, parent_link=True)
    159159                    new_class.add_to_class(attr_name, field)
    160160                else:
    161161                    field = None
  • db/models/fields/related.py

     
    374374        # object you just set.
    375375        setattr(instance, self.field.get_cache_name(), value)
    376376
     377class ReverseSingleRelatedObjectDescriptorParent(ReverseSingleRelatedObjectDescriptor):
     378    def __get__(self, instance, instance_type=None):
     379        if instance is None:
     380            return self
     381
     382        cache_name = self.field.get_cache_name()
     383        try:
     384            return getattr(instance, cache_name)
     385        except AttributeError:
     386            kwargs = {}
     387            for field in self.field.rel.to._meta.fields:
     388                if isinstance(field.rel, ManyToOneRel):
     389                    key = field.attname
     390                else:
     391                    key = field.name
     392                kwargs[key] = getattr(instance, key)
     393            rel_obj = self.field.rel.to(**kwargs)
     394            setattr(instance, cache_name, rel_obj)
     395            return rel_obj
     396
    377397class ForeignRelatedObjectsDescriptor(object):
    378398    # This class provides the functionality that makes the related-object
    379399    # managers available as attributes on a model class, for fields that have
     
    815835        'invalid': _('Model %(model)s with pk %(pk)r does not exist.')
    816836    }
    817837    description = _("Foreign Key (type determined by related field)")
    818     def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
     838    def __init__(self, to, to_field=None, rel_class=ManyToOneRel, rev_class = ReverseSingleRelatedObjectDescriptor, **kwargs):
    819839        try:
    820840            to_name = to._meta.object_name.lower()
    821841        except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
     
    837857            parent_link=kwargs.pop('parent_link', False),
    838858            on_delete=kwargs.pop('on_delete', CASCADE),
    839859        )
     860        self.rev_class = rev_class
    840861        Field.__init__(self, **kwargs)
    841862
    842863    def validate(self, value, model_instance):
     
    889910
    890911    def contribute_to_class(self, cls, name):
    891912        super(ForeignKey, self).contribute_to_class(cls, name)
    892         setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self))
     913        setattr(cls, self.name, self.rev_class(self))
    893914        if isinstance(self.rel.to, basestring):
    894915            target = self.rel.to
    895916        else:
     
    939960    rather than returning a list.
    940961    """
    941962    description = _("One-to-one relationship")
    942     def __init__(self, to, to_field=None, **kwargs):
     963    def __init__(self, to, to_field=None, rev_class = ReverseSingleRelatedObjectDescriptor, **kwargs):
    943964        kwargs['unique'] = True
    944         super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs)
     965        super(OneToOneField, self).__init__(to, to_field, OneToOneRel, rev_class, **kwargs)
    945966
    946967    def contribute_to_related_class(self, cls, related):
    947968        setattr(cls, related.get_accessor_name(),
Back to Top