Opened 17 years ago

Closed 17 years ago

Last modified 13 years ago

#7215 closed (fixed)

related_name argument for ForeignKey ignored when inheriting from abstract base class

Reported by: Joel Watts Owned by: Joel Watts
Component: Core (Other) Version: dev
Severity: Keywords: qsrf-cleanup model inheritance related
Cc: joel@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using a ForeignKey with the related_name argument in an abstract base class, the reverse accessors for child models aren't created.

The problem can be reproduced using the following models:

import datetime

from django.db import models

class Post(models.Model):
    title = models.CharField(u'Title', max_length=50)

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

    class Meta:
        abstract = True

class Comment(Attachment):
    is_spam = models.BooleanField(u'Spam')

class Update(Attachment):
    timestamp = models.DateTimeField(default=datetime.datetime.now)

Given those models, I would expect Post to have two accessors for related models: Post.attached_comment_set and Post.attached_update_set, but it doesn't. In their place is a single accessor named Post.attached_%(class)s_set.

I'm attaching a patch that rearranges django.db.models.fields.related.RelatedField.contribute_to_class enough to get the accessor methods, but I didn't see where the attached_%(class)s_set attribute was being created.

Attachments (1)

related_name.diff (3.2 KB ) - added by Joel Watts 17 years ago.
changes to RelatedField to fix related_name problem (with tests)

Download all attachments as: .zip

Change History (10)

comment:1 by Joel Watts, 17 years ago

Patch needs improvement: set

I added tests to my patch. They check to see that the accessors for the related models are created and that the attached_%(class)s_set attribute isn't created.

The changes I made to RelatedField satisfy the requirement that the accessors be created, but do not prevent the extraneous attribute from begin added.

It appears that attached_%(class)s_set thinks it's an accessor for Attachment (the abstract base class) as the test fails with these results:

Traceback (most recent call last):
    ...
AttributeError: type object 'Attachment' has no attribute '_default_manager'

by Joel Watts, 17 years ago

Attachment: related_name.diff added

changes to RelatedField to fix related_name problem (with tests)

comment:2 by Joel Watts, 17 years ago

Owner: changed from nobody to Joel Watts
Patch needs improvement: unset
Status: newassigned

Turns out I was just one if statement away from meeting all the requirements. The patch now sets the correct accessor attributes and doesn't try to create one for abstract models.

comment:3 by George Vilches, 17 years ago

Keywords: qsrf-cleanup added

comment:4 by Julien Phalip, 17 years ago

I confirm that the patch also fixes a related issue that I was experiencing as described in: http://groups.google.com/group/django-developers/browse_thread/thread/97836d6913a311db/dae5e8110139cfc9?lnk=gst&q=julien#dae5e8110139cfc9

comment:5 by Jacob, 17 years ago

milestone: 1.0

comment:6 by Jurian Botha <jurianbotha@…>, 17 years ago

Triage Stage: UnreviewedReady for checkin

I've tried this patch out and all seems fine to me. The tests also look up to scratch.

comment:7 by Malcolm Tredinnick, 17 years ago

Looks like you've understood everything, jpwatts. Nice patch.

comment:8 by Malcolm Tredinnick, 17 years ago

Resolution: fixed
Status: assignedclosed

(In [7762]) Fixed #7215 -- Create correct reverse-relation accessors when using abstract base classes. Patch from Joel Watts.

comment:9 by Jacob, 13 years ago

milestone: 1.0

Milestone 1.0 deleted

Note: See TracTickets for help on using tickets.
Back to Top