Changeset 2437
- Timestamp:
- 02/28/06 08:02:20 (3 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/magic-removal/django/db/models/fields/related.py
r2436 r2437 80 80 # This class provides the functionality that makes the related-object 81 81 # managers available as attributes on a model class, for fields that have 82 # a single "remote" value. 82 # a single "remote" value, on the class pointed to by a related field. 83 # In the example "place.restaurant", the restaurant attribute is a 84 # SingleRelatedObjectDescriptor instance. 85 def __init__(self, related): 86 self.related = related 87 88 def __get__(self, instance, instance_type=None): 89 if instance is None: 90 raise AttributeError, "%s must be accessed via instance" % self.related.opts.object_name 91 92 params = {'%s__pk' % self.related.field.name: instance._get_pk_val()} 93 rel_obj = self.related.model._default_manager.get(**params) 94 return rel_obj 95 96 def __set__(self, instance, value): 97 # Set the value of the related field 98 setattr(value, self.related.field.attname, instance) 99 100 class ReverseSingleRelatedObjectDescriptor(object): 101 # This class provides the functionality that makes the related-object 102 # managers available as attributes on a model class, for fields that have 103 # a single "remote" value, on the class that defines the related field. 83 104 # In the example "choice.poll", the poll attribute is a 84 # SingleRelatedObjectDescriptor instance.105 # ReverseSingleRelatedObjectDescriptor instance. 85 106 def __init__(self, field_with_rel): 86 self. _field = field_with_rel107 self.field = field_with_rel 87 108 88 109 def __get__(self, instance, instance_type=None): 89 110 if instance is None: 90 111 raise AttributeError, "%s must be accessed via instance" % self._field.name 91 cache_name = self. _field.get_cache_name()112 cache_name = self.field.get_cache_name() 92 113 try: 93 114 return getattr(instance, cache_name) 94 115 except AttributeError: 95 val = getattr(instance, self. _field.attname)116 val = getattr(instance, self.field.attname) 96 117 if val is None: 97 raise self. _field.rel.to.DoesNotExist98 other_field = self. _field.rel.get_related_field()118 raise self.field.rel.to.DoesNotExist 119 other_field = self.field.rel.get_related_field() 99 120 if other_field.rel: 100 params = {'%s__pk' % self. _field.rel.field_name: val}121 params = {'%s__pk' % self.field.rel.field_name: val} 101 122 else: 102 params = {'%s__exact' % self. _field.rel.field_name: val}103 rel_obj = self. _field.rel.to._default_manager.get(**params)123 params = {'%s__exact' % self.field.rel.field_name: val} 124 rel_obj = self.field.rel.to._default_manager.get(**params) 104 125 setattr(instance, cache_name, rel_obj) 105 126 return rel_obj … … 108 129 # Set the value of the related field 109 130 try: 110 val = getattr(value, self. _field.rel.get_related_field().attname)131 val = getattr(value, self.field.rel.get_related_field().attname) 111 132 except AttributeError: 112 133 val = None 113 setattr(instance, self. _field.attname, val)134 setattr(instance, self.field.attname, val) 114 135 115 136 # Set the cache to point to the new object 116 setattr(instance, self. _field.get_cache_name(), value)137 setattr(instance, self.field.get_cache_name(), value) 117 138 118 139 class ForeignRelatedObjectsDescriptor(object): … … 465 486 def contribute_to_class(self, cls, name): 466 487 super(ForeignKey, self).contribute_to_class(cls, name) 467 setattr(cls, self.name, SingleRelatedObjectDescriptor(self))488 setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self)) 468 489 469 490 def contribute_to_related_class(self, cls, related): … … 500 521 def get_validator_unique_lookup_type(self): 501 522 return '%s__%s__exact' % (self.name, self.rel.get_related_field().name) 502 523 503 524 def contribute_to_class(self, cls, name): 504 525 super(OneToOneField, self).contribute_to_class(cls, name) 505 setattr(cls, self.name, SingleRelatedObjectDescriptor(self))526 setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self)) 506 527 507 528 def contribute_to_related_class(self, cls, related): 508 setattr(cls, related.get_accessor_name(), SingleRelatedObjectDescriptor( self))529 setattr(cls, related.get_accessor_name(), SingleRelatedObjectDescriptor(related)) 509 530 if not cls._meta.one_to_one_field: 510 531 cls._meta.one_to_one_field = self … … 633 654 self.lookup_overrides = lookup_overrides or {} 634 655 self.raw_id_admin = raw_id_admin 656 self.multiple = True 635 657 636 658 def get_related_field(self): … … 648 670 self.lookup_overrides = lookup_overrides or {} 649 671 self.raw_id_admin = raw_id_admin 650 672 self.multiple = False 673 651 674 class ManyToMany: 652 675 def __init__(self, to, singular=None, related_name=None, … … 660 683 self.raw_id_admin = raw_id_admin 661 684 self.symmetrical = symmetrical 685 self.multiple = True 686 662 687 assert not (self.raw_id_admin and self.filter_interface), "ManyToMany relationships may not use both raw_id_admin and filter_interface" django/branches/magic-removal/django/db/models/related.py
r2381 r2437 74 74 # many-to-many objects. It uses the lower-cased object_name + "_set", 75 75 # but this can be overridden with the "related_name" option. 76 return self.field.rel.related_name or (self.opts.object_name.lower() + '_set') 76 if self.field.rel.multiple: 77 return self.field.rel.related_name or (self.opts.object_name.lower() + '_set') 78 else: 79 return self.field.rel.related_name or (self.opts.object_name.lower()) django/branches/magic-removal/tests/modeltests/one_to_one/models.py
r2409 r2437 54 54 Traceback (most recent call last): 55 55 ... 56 DoesNotExist: Restaurant does not exist for {'place__ id__exact': ...}56 DoesNotExist: Restaurant does not exist for {'place__pk': ...} 57 57 58 58 # Restaurant.objects.all() just returns the Restaurants, not the Places.
