Django

Code

Ticket #7215: related_name.diff

File related_name.diff, 3.2 kB (added by jpwatts, 7 months ago)

changes to RelatedField to fix related_name problem (with tests)

  • django/db/models/fields/related.py

    old new  
    103103 
    104104        if hasattr(sup, 'contribute_to_class'): 
    105105            sup.contribute_to_class(cls, name) 
     106 
     107        if not cls._meta.abstract and self.rel.related_name: 
     108            self.rel.related_name = self.rel.related_name % {'class': cls.__name__.lower()} 
     109 
    106110        other = self.rel.to 
    107111        if isinstance(other, basestring): 
    108112            add_lazy_relation(cls, self, other) 
    109113        else: 
    110114            self.do_related_class(other, cls) 
    111         if not cls._meta.abstract and self.rel.related_name: 
    112             self.rel.related_name = self.rel.related_name % {'class': cls.__name__.lower()} 
    113115 
    114116    def set_attributes_from_rel(self): 
    115117        self.name = self.name or (self.rel.to._meta.object_name.lower() + '_' + self.rel.to._meta.pk.name) 
     
    119121    def do_related_class(self, other, cls): 
    120122        self.set_attributes_from_rel() 
    121123        related = RelatedObject(other, cls, self) 
    122         self.contribute_to_related_class(other, related) 
     124        if not cls._meta.abstract: 
     125            self.contribute_to_related_class(other, related) 
    123126 
    124127    def get_db_prep_lookup(self, lookup_type, value): 
    125128        # If we are doing a lookup on a Related Field, we must be 
  • tests/modeltests/model_inheritance/models.py

    old new  
    3939        pass 
    4040 
    4141# 
     42# Abstract base classes with related models 
     43# 
     44 
     45class Post(models.Model): 
     46    title = models.CharField(max_length=50) 
     47 
     48class Attachment(models.Model): 
     49    post = models.ForeignKey(Post, related_name='attached_%(class)s_set') 
     50    content = models.TextField() 
     51 
     52    class Meta: 
     53        abstract = True 
     54 
     55    def __unicode__(self): 
     56        return self.content 
     57 
     58class Comment(Attachment): 
     59    is_spam = models.BooleanField() 
     60 
     61class Link(Attachment): 
     62    url = models.URLField() 
     63 
     64# 
    4265# Multi-table inheritance 
    4366# 
    4467 
     
    128151    ... 
    129152AttributeError: type object 'CommonInfo' has no attribute 'objects' 
    130153 
     154# Create a Post 
     155>>> post = Post(title='Lorem Ipsum') 
     156>>> post.save() 
     157 
     158# The Post model should have accessors for the Comment and Link models 
     159>>> post.attached_comment_set.create(content='Save $ on V1agr@', is_spam=True) 
     160<Comment: Save $ on V1agr@> 
     161>>> post.attached_link_set.create(content='The Web framework for perfectionists with deadlines.', url='http://www.djangoproject.com/') 
     162<Link: The Web framework for perfectionists with deadlines.> 
     163 
     164# The Post model should not have an attribute 'attached_%(class)s_set' 
     165>>> getattr(post, 'attached_%(class)s_set') 
     166Traceback (most recent call last): 
     167    ... 
     168AttributeError: 'Post' object has no attribute 'attached_%(class)s_set' 
     169 
    131170# The Place/Restaurant/ItalianRestaurant models, on the other hand, all exist 
    132171# as independent models. However, the subclasses also have transparent access 
    133172# to the fields of their ancestors.