Opened 6 years ago

Last modified 2 years ago

#9501 new Bug

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

Description

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 (13)

comment:1 Changed 6 years ago by Beetle_B

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

"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 6 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 6 years ago by mrmachine

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

  • Resolution set to invalid
  • Status changed from new to closed

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

comment:5 Changed 6 years ago by jacob

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

comment:6 Changed 6 years ago by Beetle_B

  • Cc mueen@… added
  • Resolution invalid deleted
  • Status changed from closed to reopened
  • Version changed from 1.0 to SVN

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

  • Triage Stage changed from Unreviewed to Accepted

comment:8 Changed 4 years ago by gabrielhurley

  • Component changed from Contrib apps to contrib.contenttypes

comment:9 Changed 4 years ago by lukeplant

  • Severity set to Normal
  • Type set to Bug

comment:10 Changed 3 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:11 Changed 3 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:12 Changed 2 years ago by ramiro

See also #13203.

comment:13 Changed 2 years ago by aaugustin

  • Status changed from reopened to new
Note: See TracTickets for help on using tickets.
Back to Top