danirus / django-comments-xtd

A pluggable Django comments application with thread support, follow-up notifications, mail confirmation, like/dislike flags, moderation, a ReactJS plugin and Bootstrap 5.3.
https://django-comments-xtd.readthedocs.io
BSD 2-Clause "Simplified" License
594 stars 158 forks source link

Deleting all comments associated with an object #193

Open jimkring opened 4 years ago

jimkring commented 4 years ago

Hi there. I'd like some way to delete all comments associated with an object, when the object is deleted. I just did a test and I see that this does not currently happen. Are there any housekeeping functions that do this?

danirus commented 4 years ago

No, there's no special function for this. The way to delete all the comments sent to an instance of a model Story of an app registered as blog, via a receiver function of the post_delete signal would be:

@receiver(post_delete, sender=Story)
def delete_comments(sender, instance, **kwargs):
    ct = ContentType.objects.get(app_label="blog", model="story")
    XtdComment.objects.filter(content_type=ct, object_pk=instance.id).delete()
jimkring commented 4 years ago

Thanks @danirus! That's a very helpful pointer and should get me going in the right direction.

jimkring commented 4 years ago

One more question -- just a thought?

Is it possible to get the app_label and model names programmatically from the Story class that's passed in, so that this function could be generalized? I'm not a django guru, so thanks for any pointers. Of course, the solution you posted is good enough for my needs, right now.

jimkring commented 4 years ago

@danirus I was thinking that this would be a great use case to document: https://github.com/danirus/django-comments-xtd/issues/197

jimkring commented 4 years ago

@danirus Update: I was able to generize this a little by getting the model name (in lowercase) programmatically using: sender.__name__.lower()

@receiver(post_delete, sender=Idea)
def delete_comments(sender, instance, **kwargs):
    ct = ContentType.objects.get(app_label="myapp", model=sender.__name__.lower())
    XtdComment.objects.filter(content_type=ct, object_pk=instance.id).delete()

Now, I just need to figure out hot to get the app_label from the sender model instance.

danirus commented 4 years ago

You can use the Meta class from inside the Model class. It's accessible via the _meta attribute of any model class. Using the label attribute of _meta you could get the app_label.

ogurec-ogurec commented 3 years ago

Tell please, is it possible to somehow make it so that when a user is deleted, his comments are also deleted?

danirus commented 3 years ago

The solution is explained along this thread. The code two comments above shows how to delete comments posted to an object. You can write a receiver in the same way called when a user is deleted. Bear in mind that you might break the comments structure by doing so. Deleting a parent comment will leave all nested comments referencing a comment that doesn't exist. You could leave the comment but anonymized, or display a message saying that the user that posted the comment deleted the account. Either way I would recommend not to delete the comment. When the user is deleted the signals pre_delete and post_delete are triggered.