Django

Code

Changeset 2437

Show
Ignore:
Timestamp:
02/28/06 08:02:20 (3 years ago)
Author:
russellm
Message:

magic-removal: Added fixes to OneToOne? descriptors and RelatedObjects? to get one_to_one unit tests to pass. Still requires work on and extra unit tests for set on SingleRelatedObjectDescriptor?.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/magic-removal/django/db/models/fields/related.py

    r2436 r2437  
    8080    # This class provides the functionality that makes the related-object 
    8181    # 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             
     100class 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. 
    83104    # In the example "choice.poll", the poll attribute is a 
    84     # SingleRelatedObjectDescriptor instance. 
     105    # ReverseSingleRelatedObjectDescriptor instance. 
    85106    def __init__(self, field_with_rel): 
    86         self._field = field_with_rel 
     107        self.field = field_with_rel 
    87108 
    88109    def __get__(self, instance, instance_type=None): 
    89110        if instance is None: 
    90111            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() 
    92113        try: 
    93114            return getattr(instance, cache_name) 
    94115        except AttributeError: 
    95             val = getattr(instance, self._field.attname) 
     116            val = getattr(instance, self.field.attname) 
    96117            if val is None: 
    97                 raise self._field.rel.to.DoesNotExist 
    98             other_field = self._field.rel.get_related_field() 
     118                raise self.field.rel.to.DoesNotExist 
     119            other_field = self.field.rel.get_related_field() 
    99120            if other_field.rel: 
    100                 params = {'%s__pk' % self._field.rel.field_name: val} 
     121                params = {'%s__pk' % self.field.rel.field_name: val} 
    101122            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) 
    104125            setattr(instance, cache_name, rel_obj) 
    105126            return rel_obj 
     
    108129        # Set the value of the related field 
    109130        try: 
    110             val = getattr(value, self._field.rel.get_related_field().attname) 
     131            val = getattr(value, self.field.rel.get_related_field().attname) 
    111132        except AttributeError: 
    112133            val = None 
    113         setattr(instance, self._field.attname, val) 
     134        setattr(instance, self.field.attname, val) 
    114135             
    115136        # 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) 
    117138         
    118139class ForeignRelatedObjectsDescriptor(object): 
     
    465486    def contribute_to_class(self, cls, name): 
    466487        super(ForeignKey, self).contribute_to_class(cls, name) 
    467         setattr(cls, self.name, SingleRelatedObjectDescriptor(self)) 
     488        setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self)) 
    468489 
    469490    def contribute_to_related_class(self, cls, related): 
     
    500521    def get_validator_unique_lookup_type(self): 
    501522        return '%s__%s__exact' % (self.name, self.rel.get_related_field().name) 
    502  
     523         
    503524    def contribute_to_class(self, cls, name): 
    504525        super(OneToOneField, self).contribute_to_class(cls, name) 
    505         setattr(cls, self.name, SingleRelatedObjectDescriptor(self)) 
     526        setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self)) 
    506527 
    507528    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)) 
    509530        if not cls._meta.one_to_one_field: 
    510531           cls._meta.one_to_one_field = self 
     
    633654        self.lookup_overrides = lookup_overrides or {} 
    634655        self.raw_id_admin = raw_id_admin 
     656        self.multiple = True 
    635657 
    636658    def get_related_field(self): 
     
    648670        self.lookup_overrides = lookup_overrides or {} 
    649671        self.raw_id_admin = raw_id_admin 
    650  
     672        self.multiple = False 
     673         
    651674class ManyToMany: 
    652675    def __init__(self, to, singular=None, related_name=None, 
     
    660683        self.raw_id_admin = raw_id_admin 
    661684        self.symmetrical = symmetrical 
     685        self.multiple = True 
     686 
    662687        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  
    7474        # many-to-many objects. It uses the lower-cased object_name + "_set", 
    7575        # 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  
    5454Traceback (most recent call last): 
    5555    ... 
    56 DoesNotExist: Restaurant does not exist for {'place__id__exact': ...} 
     56DoesNotExist: Restaurant does not exist for {'place__pk': ...} 
    5757 
    5858# Restaurant.objects.all() just returns the Restaurants, not the Places.