Skip to content

Commit ab3e0e6

Browse files
atodorovclaudep
authored andcommitted
Add manage.py delete_stale_comments command
1 parent 62ccc2f commit ab3e0e6

File tree

7 files changed

+93
-0
lines changed

7 files changed

+93
-0
lines changed

HISTORY.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Unreleased
77
----------
88

99
* Dropped support for Django 1.11, 2.0, and 2.1.
10+
* Added the ``delete_stale_comments`` management command.
1011

1112
2.0.0 (2020-12-20)
1213
------------------

django_comments/management/__init__.py

Whitespace-only changes.

django_comments/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from django.core.management.base import BaseCommand
2+
3+
from django_comments.models import Comment
4+
5+
6+
class Command(BaseCommand):
7+
help = ("Remove comments for which the related objects "
8+
"don't exist anymore!")
9+
10+
def add_arguments(self, parser):
11+
parser.add_argument(
12+
'-y', '--yes', default='x', action='store_const', const='y',
13+
dest='answer', help='Automatically confirm deletion',
14+
)
15+
16+
def handle(self, *args, **kwargs):
17+
verbose = kwargs['verbosity'] >= 1
18+
answer = kwargs['answer']
19+
20+
# -v0 sets --yes
21+
if not verbose:
22+
answer = 'y'
23+
24+
for comment in Comment.objects.all():
25+
if comment.content_object is None:
26+
if verbose:
27+
self.stdout.write(
28+
"Comment `%s' to non-existing `%s' with PK `%s'" %
29+
(comment, comment.content_type.model, comment.object_pk))
30+
31+
while answer not in 'yn':
32+
answer = input("Do you wish to delete? [yN] ")
33+
if not answer:
34+
answer = 'x'
35+
continue
36+
answer = answer[0].lower()
37+
38+
if answer == 'y' :
39+
comment.delete()
40+
41+
if verbose:
42+
self.stdout.write("Deleted comment `%s'" % comment)

docs/index.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Contents
2222
quickstart
2323
models
2424
signals
25+
management_commands
2526
custom
2627
forms
2728
moderation

docs/management_commands.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
===================
2+
Management commands
3+
===================
4+
5+
delete_stale_comments
6+
=====================
7+
8+
Remove comments for which the related objects don't exist anymore!
9+
This is a handy house-keeping command because the comment model
10+
doesn't enforce cascade delete on the database level! Run:
11+
12+
.. code-block:: shell
13+
14+
manage.py delete_stale_comments
15+
16+
This command supports the ``--yes`` flag to automatically confirm
17+
suggested deletions, suitable for running via cron.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from django.core.management import call_command
2+
3+
from django_comments.models import Comment
4+
5+
from . import CommentTestCase
6+
from testapp.models import Article
7+
8+
9+
class CommentManagerTests(CommentTestCase):
10+
11+
def testDoesNotRemoveWhenNoStaleComments(self):
12+
self.createSomeComments()
13+
initial_count = Comment.objects.count()
14+
15+
call_command("delete_stale_comments", "--yes", verbosity=0)
16+
17+
self.assertEqual(initial_count, Comment.objects.count())
18+
19+
def testRemovesWhenParentObjectsAreMissing(self):
20+
self.createSomeComments()
21+
initial_count = Comment.objects.count()
22+
article_comments_count = Comment.objects.for_model(Article).count()
23+
self.assertGreater(article_comments_count, 0)
24+
25+
# removing articles will not remove associated comments
26+
Article.objects.all().delete()
27+
self.assertEqual(initial_count, Comment.objects.count())
28+
29+
call_command("delete_stale_comments", "--yes", verbosity=0)
30+
31+
self.assertEqual(0, Comment.objects.for_model(Article).count())
32+
self.assertEqual(initial_count - article_comments_count, Comment.objects.count())

0 commit comments

Comments
 (0)