Ticket #7215: related_name.diff

File related_name.diff, 3.2 KB (added by Joel Watts, 16 years ago)

changes to RelatedField to fix related_name problem (with tests)

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

     
    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

     
    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.
Back to Top