Django

Code

Changeset 6900

Show
Ignore:
Timestamp:
12/09/07 01:12:07 (9 months ago)
Author:
mtredinnick
Message:

Fixed #3906 -- Fixed the reverse_m2m_name for a generic relation. Refs #2749.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/contenttypes/generic.py

    r5967 r6900  
    1717    fields. 
    1818    """ 
    19      
     19 
    2020    def __init__(self, ct_field="content_type", fk_field="object_id"): 
    2121        self.ct_field = ct_field 
    2222        self.fk_field = fk_field 
    23          
     23 
    2424    def contribute_to_class(self, cls, name): 
    25         # Make sure the fields exist (these raise FieldDoesNotExist,  
     25        # Make sure the fields exist (these raise FieldDoesNotExist, 
    2626        # which is a fine error to raise here) 
    2727        self.name = name 
    2828        self.model = cls 
    2929        self.cache_attr = "_%s_cache" % name 
    30          
     30 
    3131        # For some reason I don't totally understand, using weakrefs here doesn't work. 
    3232        dispatcher.connect(self.instance_pre_init, signal=signals.pre_init, sender=cls, weak=False) 
     
    3636 
    3737    def instance_pre_init(self, signal, sender, args, kwargs): 
    38         # Handle initalizing an object with the generic FK instaed of  
    39         # content-type/object-id fields.         
     38        # Handle initalizing an object with the generic FK instaed of 
     39        # content-type/object-id fields. 
    4040        if self.name in kwargs: 
    4141            value = kwargs.pop(self.name) 
    4242            kwargs[self.ct_field] = self.get_content_type(value) 
    4343            kwargs[self.fk_field] = value._get_pk_val() 
    44              
     44 
    4545    def get_content_type(self, obj): 
    4646        # Convenience function using get_model avoids a circular import when using this model 
    4747        ContentType = get_model("contenttypes", "contenttype") 
    4848        return ContentType.objects.get_for_model(obj) 
    49          
     49 
    5050    def __get__(self, instance, instance_type=None): 
    5151        if instance is None: 
     
    7878        setattr(instance, self.fk_field, fk) 
    7979        setattr(instance, self.cache_attr, value) 
    80      
     80 
    8181class GenericRelation(RelatedField, Field): 
    8282    """Provides an accessor to generic related objects (i.e. comments)""" 
     
    8484    def __init__(self, to, **kwargs): 
    8585        kwargs['verbose_name'] = kwargs.get('verbose_name', None) 
    86         kwargs['rel'] = GenericRel(to,  
     86        kwargs['rel'] = GenericRel(to, 
    8787                            related_name=kwargs.pop('related_name', None), 
    8888                            limit_choices_to=kwargs.pop('limit_choices_to', None), 
    8989                            symmetrical=kwargs.pop('symmetrical', True)) 
    90                              
     90 
    9191        # Override content-type/object-id field names on the related class 
    9292        self.object_id_field_name = kwargs.pop("object_id_field", "object_id") 
    93         self.content_type_field_name = kwargs.pop("content_type_field", "content_type")                 
    94          
     93        self.content_type_field_name = kwargs.pop("content_type_field", "content_type") 
     94 
    9595        kwargs['blank'] = True 
    9696        kwargs['editable'] = False 
     
    117117    def m2m_column_name(self): 
    118118        return self.object_id_field_name 
    119          
     119 
    120120    def m2m_reverse_name(self): 
    121         return self.object_id_field_name 
     121        return self.model._meta.pk.column 
    122122 
    123123    def contribute_to_class(self, cls, name): 
     
    132132    def contribute_to_related_class(self, cls, related): 
    133133        pass 
    134          
     134 
    135135    def set_attributes_from_rel(self): 
    136136        pass 
     
    138138    def get_internal_type(self): 
    139139        return "ManyToManyField" 
    140          
     140 
    141141class ReverseGenericRelatedObjectsDescriptor(object): 
    142142    """ 
     
    194194    Manager) and adds behavior for generic related objects. 
    195195    """ 
    196      
     196 
    197197    class GenericRelatedObjectManager(superclass): 
    198198        def __init__(self, model=None, core_filters=None, instance=None, symmetrical=None, 
    199199                     join_table=None, source_col_name=None, target_col_name=None, content_type=None, 
    200200                     content_type_field_name=None, object_id_field_name=None): 
    201              
     201 
    202202            super(GenericRelatedObjectManager, self).__init__() 
    203203            self.core_filters = core_filters or {} 
     
    213213            self.object_id_field_name = object_id_field_name 
    214214            self.pk_val = self.instance._get_pk_val() 
    215                          
     215 
    216216        def get_query_set(self): 
    217217            query = { 
    218                 '%s__pk' % self.content_type_field_name : self.content_type.id,  
     218                '%s__pk' % self.content_type_field_name : self.content_type.id, 
    219219                '%s__exact' % self.object_id_field_name : self.pk_val, 
    220220            } 
  • django/trunk/tests/modeltests/generic_relations/models.py

    r5876 r6900  
    1919    content_type = models.ForeignKey(ContentType) 
    2020    object_id = models.PositiveIntegerField() 
    21      
     21 
    2222    content_object = generic.GenericForeignKey() 
    23      
     23 
    2424    class Meta: 
    2525        ordering = ["tag"] 
    26      
     26 
    2727    def __unicode__(self): 
    2828        return self.tag 
     
    3131    common_name = models.CharField(max_length=150) 
    3232    latin_name = models.CharField(max_length=150) 
    33      
     33 
    3434    tags = generic.GenericRelation(TaggedItem) 
    3535 
    3636    def __unicode__(self): 
    3737        return self.common_name 
    38          
     38 
    3939class Vegetable(models.Model): 
    4040    name = models.CharField(max_length=150) 
    4141    is_yucky = models.BooleanField(default=True) 
    42      
     42 
    4343    tags = generic.GenericRelation(TaggedItem) 
    44      
     44 
    4545    def __unicode__(self): 
    4646        return self.name 
    47      
     47 
    4848class Mineral(models.Model): 
    4949    name = models.CharField(max_length=150) 
    5050    hardness = models.PositiveSmallIntegerField() 
    51      
     51 
    5252    # note the lack of an explicit GenericRelation here... 
    53      
     53 
    5454    def __unicode__(self): 
    5555        return self.name 
    56          
     56 
    5757__test__ = {'API_TESTS':""" 
    5858# Create the world in 7 lines of code... 
     
    118118[(u'clearish', <ContentType: mineral>, 1), (u'fatty', <ContentType: vegetable>, 2), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2)] 
    119119 
    120 # If Generic Relation is not explicitly defined, any related objects  
     120# If Generic Relation is not explicitly defined, any related objects 
    121121# remain after deletion of the source object. 
    122122>>> quartz.delete() 
     
    124124[(u'clearish', <ContentType: mineral>, 1), (u'fatty', <ContentType: vegetable>, 2), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2)] 
    125125 
    126 # If you delete a tag, the objects using the tag are unaffected  
     126# If you delete a tag, the objects using the tag are unaffected 
    127127# (other than losing a tag) 
    128128>>> tag = TaggedItem.objects.get(id=1) 
     
    133133[(u'clearish', <ContentType: mineral>, 1), (u'salty', <ContentType: vegetable>, 2), (u'shiny', <ContentType: animal>, 2)] 
    134134 
     135>>> ctype = ContentType.objects.get_for_model(lion) 
     136>>> Animal.objects.filter(tags__content_type=ctype) 
     137[<Animal: Platypus>] 
     138 
    135139"""}