Opened 10 years ago

Closed 3 years ago

Last modified 3 years ago

#9501 closed Bug (fixed)

Generic relations to derived models won't allow for deletion of objects those models are attached to.

Reported by: Beetle_B Owned by: nobody
Component: contrib.contenttypes Version: master
Severity: Normal Keywords:
Cc: mueen@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


OK. Here's my scenario. I'm working with a blog, and with a comments app.

Let's say the comment's model is Comment. As it can be attached to any object, it has a generic foreign key to ContentType:

    # Generic Foreign Key Fields
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField(_('object ID'))
    content_object = generic.GenericForeignKey()

Now I didn't like the Comment model: It was lacking an important field (comment_html). I didn't want to touch the comment's app's source code. So I created a new model that inherited from Comment and called it CommentMod. It consists of simply the extra field and overrides the save method.

The blog app has an Entry model. In that model, I put:

    comments = GenericRelation(CommentMod)

The goal was that if I delete a blog entry, it should delete all comments associated with it.

However, when I try to delete a blog entry that has comments via the admin, I get an error. Upon observing the SQL, it turns out that it can't find an 'object_id' and 'content_type_id' columns in the CommentMod tables.

It can't do that because it's a derived model. Those columns are in the Comment tables.

I tried changing it to:

    comments = GenericRelation(Comment)

But then if I try to delete Entry, I get a foreign key constraint problem from the DB (MySQL).

So it seems that I can't expect generic relations to work with derived models. I don't know if this is by design - if it's not, then it's a bug.

For now, I'll just create a GenericForeignKey in the derived models as well. Not sure if it will work...

Change History (15)

comment:1 Changed 10 years ago by Beetle_B

"For now, I'll just create a GenericForeignKey? in the derived models as well. Not sure if it will work..."

It didn't.

Or perhaps it worked too well.

Specifically, it no longer gives an error. It deletes all the entries in the CommentMod table. However, those entries still remain in the Comment table of the DB.

comment:2 Changed 10 years ago by Beetle_B

For now, working around this by overriding the delete method of Entry and manually deleting all related comments.

comment:3 Changed 9 years ago by Tai Lee

The comments app uses object_pk instead of the default object_id. Does it help if you specify your comments field as GenericRelation(CommentMod, object_id_field='object_pk')?

comment:4 Changed 9 years ago by Jacob

Resolution: invalid
Status: newclosed

I'm pretty sure that, as mrmachine says, is user error. Please reopen if I'm wrong.

comment:5 Changed 9 years ago by Jacob

... and if it's not user error, this is a duplicate of #9546.

comment:6 Changed 9 years ago by Beetle_B

Cc: mueen@… added
Resolution: invalid
Status: closedreopened
Version: 1.0SVN

Sorry for the long delay.

I just synced to the latest SVN, and the problem remains.

Or perhaps I'm doing it wrong. Here's what I'm doing

from django.contrib.comments.models import Comment
from django.contrib.contenttypes import generic

class DerComment(Comment):
  # Some derived material goes here.

class Entry(models.Model):
  # Some fields related to the entry. Pretend it's a blog.

  comments = generic.GenericRelation(DerComment, object_id_field='object_pk')

Now I go create an Entry. I then add a dercomment to it. When I delete the entry (via the admin), the comment remains.

If instead of making a generic relation to DerComment, I had made it to Comment, then when I delete the entry, the admin shows no Comments, but it claims to have 1 DerComment in the database (yet the admin doesn't actually list the comment.

Note that I'm subclassing the django.contrib's comment, which is not an abstract model.

Am I doing something wrong?

comment:7 Changed 9 years ago by Alex Gaynor

Triage Stage: UnreviewedAccepted

comment:8 Changed 7 years ago by Gabriel Hurley

Component: Contrib appscontrib.contenttypes

comment:9 Changed 7 years ago by Luke Plant

Severity: Normal
Type: Bug

comment:10 Changed 6 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:11 Changed 6 years ago by Aymeric Augustin

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:12 Changed 5 years ago by Ramiro Morales

See also #13203.

comment:13 Changed 5 years ago by Aymeric Augustin

Status: reopenednew

comment:14 Changed 3 years ago by Tim Graham

Resolution: fixed
Status: newclosed

As far as I can tell, this issue has been fixed (I tried to reproduce with similar models to those in comment 6). I added an assertion as part of a pull request. Please reopen with more details if the issue remains.

comment:15 Changed 3 years ago by Tim Graham <timograham@…>

In 58c7ff3:

Refs #13203, #9501 -- Added a test for generic relations to child models.

Fixed in 97774429aeb54df4c09895c07cd1b09e70201f7d.

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