Code

Opened 6 years ago

Closed 6 years ago

Last modified 3 years ago

#7215 closed (fixed)

related_name argument for ForeignKey ignored when inheriting from abstract base class

Reported by: jpwatts Owned by: jpwatts
Component: Core (Other) Version: master
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: UI/UX:

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 jpwatts 6 years ago.
changes to RelatedField to fix related_name problem (with tests)

Download all attachments as: .zip

Change History (10)

comment:1 Changed 6 years ago by jpwatts

  • Needs documentation unset
  • Needs tests unset
  • 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'

Changed 6 years ago by jpwatts

changes to RelatedField to fix related_name problem (with tests)

comment:2 Changed 6 years ago by jpwatts

  • Owner changed from nobody to jpwatts
  • Patch needs improvement unset
  • Status changed from new to assigned

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 Changed 6 years ago by gav

  • Keywords qsrf-cleanup added

comment:4 Changed 6 years ago by julien

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 Changed 6 years ago by jacob

  • milestone set to 1.0

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

  • Triage Stage changed from Unreviewed to Ready for checkin

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

comment:7 Changed 6 years ago by mtredinnick

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

comment:8 Changed 6 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from assigned to closed

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

comment:9 Changed 3 years ago by jacob

  • milestone 1.0 deleted

Milestone 1.0 deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.