Commit d2ce1df0 authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

Fixed #7215 -- Create correct reverse-relation accessors when using abstract...

Fixed #7215 -- Create correct reverse-relation accessors when using abstract base classes. Patch from Joel Watts.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@7762 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent ba015e0a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -376,6 +376,7 @@ answer newbie questions, and generally made Django that much better:
    Wang Chun <wangchun@exoweb.net>
    Filip Wasilewski <filip.wasilewski@gmail.com>
    Dan Watson <http://theidioteque.net/>
    Joel Watts <joel@joelwatts.com>
    Chris Wesseling <Chris.Wesseling@cwi.nl>
    James Wheare <django@sparemint.com>
    charly.wilhelm@gmail.com
+6 −3
Original line number Diff line number Diff line
@@ -103,13 +103,15 @@ class RelatedField(object):

        if hasattr(sup, 'contribute_to_class'):
            sup.contribute_to_class(cls, name)

        if not cls._meta.abstract and self.rel.related_name:
            self.rel.related_name = self.rel.related_name % {'class': cls.__name__.lower()}

        other = self.rel.to
        if isinstance(other, basestring):
            add_lazy_relation(cls, self, other)
        else:
            self.do_related_class(other, cls)
        if not cls._meta.abstract and self.rel.related_name:
            self.rel.related_name = self.rel.related_name % {'class': cls.__name__.lower()}

    def set_attributes_from_rel(self):
        self.name = self.name or (self.rel.to._meta.object_name.lower() + '_' + self.rel.to._meta.pk.name)
@@ -119,6 +121,7 @@ class RelatedField(object):
    def do_related_class(self, other, cls):
        self.set_attributes_from_rel()
        related = RelatedObject(other, cls, self)
        if not cls._meta.abstract:
            self.contribute_to_related_class(other, related)

    def get_db_prep_lookup(self, lookup_type, value):
+42 −3
Original line number Diff line number Diff line
@@ -38,6 +38,29 @@ class Student(CommonInfo):
    class Meta:
        pass

#
# Abstract base classes with related models
#

class Post(models.Model):
    title = models.CharField(max_length=50)

class Attachment(models.Model):
    post = models.ForeignKey(Post, related_name='attached_%(class)s_set')
    content = models.TextField()

    class Meta:
        abstract = True

    def __unicode__(self):
        return self.content

class Comment(Attachment):
    is_spam = models.BooleanField()

class Link(Attachment):
    url = models.URLField()

#
# Multi-table inheritance
#
@@ -128,9 +151,25 @@ Traceback (most recent call last):
    ...
AttributeError: type object 'CommonInfo' has no attribute 'objects'

# The Place/Restaurant/ItalianRestaurant models, on the other hand, all exist
# as independent models. However, the subclasses also have transparent access
# to the fields of their ancestors.
# Create a Post
>>> post = Post(title='Lorem Ipsum')
>>> post.save()

# The Post model has distinct accessors for the Comment and Link models.
>>> post.attached_comment_set.create(content='Save $ on V1agr@', is_spam=True)
<Comment: Save $ on V1agr@>
>>> post.attached_link_set.create(content='The Web framework for perfectionists with deadlines.', url='http://www.djangoproject.com/')
<Link: The Web framework for perfectionists with deadlines.>

# The Post model doesn't have an attribute called 'attached_%(class)s_set'.
>>> getattr(post, 'attached_%(class)s_set')
Traceback (most recent call last):
    ...
AttributeError: 'Post' object has no attribute 'attached_%(class)s_set'

# The Place/Restaurant/ItalianRestaurant models all exist as independent
# models. However, the subclasses also have transparent access to the fields of
# their ancestors.

# Create a couple of Places.
>>> p1 = Place(name='Master Shakes', address='666 W. Jersey')