1
.. _ref-contrib-comments-moderation:
3
==========================
4
Generic comment moderation
5
==========================
7
.. module:: django.contrib.comments.moderation
8
:synopsis: Support for automatic comment moderation.
10
Django's bundled comments application is extremely useful on its own,
11
but the amount of comment spam circulating on the Web today
12
essentially makes it necessary to have some sort of automatic
13
moderation system in place for any application which makes use of
14
comments. To make this easier to handle in a consistent fashion,
15
``django.contrib.comments.moderation`` provides a generic, extensible
16
comment-moderation system which can be applied to any model or set of
17
models which want to make use of Django's comment system.
23
The entire system is contained within ``django.contrib.comments.moderation``,
24
and uses a two-step process to enable moderation for any given model:
26
1. A subclass of :class:`CommentModerator`
27
is defined which specifies the moderation options the model wants to
30
2. The model is registered with the moderation system, passing in the
31
model class and the class which specifies its moderation options.
33
A simple example is the best illustration of this. Suppose we have the
34
following model, which would represent entries in a weblog::
36
from django.db import models
38
class Entry(models.Model):
39
title = models.CharField(maxlength=250)
40
body = models.TextField()
41
pub_date = models.DateTimeField()
42
enable_comments = models.BooleanField()
44
Now, suppose that we want the following steps to be applied whenever a
45
new comment is posted on an ``Entry``:
47
1. If the ``Entry``'s ``enable_comments`` field is ``False``, the
48
comment will simply be disallowed (i.e., immediately deleted).
50
2. If the ``enable_comments`` field is ``True``, the comment will be
53
3. Once the comment is saved, an email should be sent to site staff
54
notifying them of the new comment.
56
Accomplishing this is fairly straightforward and requires very little
59
from django.contrib.comments.moderation import CommentModerator, moderator
61
class EntryModerator(CommentModerator):
62
email_notification = True
63
enable_field = 'enable_comments'
65
moderator.register(Entry, EntryModerator)
67
The :class:`CommentModerator` class pre-defines a number of useful moderation
68
options which subclasses can enable or disable as desired, and ``moderator``
69
knows how to work with them to determine whether to allow a comment, whether
70
to moderate a comment which will be allowed to post, and whether to email
71
notifications of new comments.
73
Built-in moderation options
74
---------------------------
76
.. class:: CommentModerator
78
Most common comment-moderation needs can be handled by subclassing
79
:class:`CommentModerator` and
80
changing the values of pre-defined attributes; the full range of built-in
81
options is as follows.
83
.. attribute:: auto_close_field
85
If this is set to the name of a
86
:class:`~django.db.models.fields.DateField` or
87
:class:`~django.db.models.fields.DateTimeField` on the model for which
88
comments are being moderated, new comments for objects of that model
89
will be disallowed (immediately deleted) when a certain number of days
90
have passed after the date specified in that field. Must be
91
used in conjunction with :attr:`close_after`, which specifies the
92
number of days past which comments should be
93
disallowed. Default value is ``None``.
95
.. attribute:: auto_moderate_field
97
Like :attr:`auto_close_field`, but instead of outright deleting
98
new comments when the requisite number of days have elapsed,
99
it will simply set the ``is_public`` field of new comments to
100
``False`` before saving them. Must be used in conjunction with
101
:attr:`moderate_after`, which specifies the number of days past
102
which comments should be moderated. Default value is ``None``.
104
.. attribute:: close_after
106
If :attr:`auto_close_field` is used, this must specify the number
107
of days past the value of the field specified by
108
:attr:`auto_close_field` after which new comments for an object
109
should be disallowed. Default value is ``None``.
111
.. attribute:: email_notification
113
If ``True``, any new comment on an object of this model which
114
survives moderation (i.e., is not deleted) will generate an
115
email to site staff. Default value is ``False``.
117
.. attribute:: enable_field
119
If this is set to the name of a
120
:class:`~django.db.models.fields.BooleanField` on the model
121
for which comments are being moderated, new comments on
122
objects of that model will be disallowed (immediately deleted)
123
whenever the value of that field is ``False`` on the object
124
the comment would be attached to. Default value is ``None``.
126
.. attribute:: moderate_after
128
If :attr:`auto_moderate_field` is used, this must specify the number
129
of days past the value of the field specified by
130
:attr:`auto_moderate_field` after which new comments for an object
131
should be marked non-public. Default value is ``None``.
133
Simply subclassing :class:`CommentModerator` and changing the values of these
134
options will automatically enable the various moderation methods for any
135
models registered using the subclass.
137
Adding custom moderation methods
138
--------------------------------
140
For situations where the built-in options listed above are not
141
sufficient, subclasses of :class:`CommentModerator` can also override
142
the methods which actually perform the moderation, and apply any logic
143
they desire. :class:`CommentModerator` defines three methods which
144
determine how moderation will take place; each method will be called
145
by the moderation system and passed two arguments: ``comment``, which
146
is the new comment being posted, ``content_object``, which is the
147
object the comment will be attached to, and ``request``, which is the
148
:class:`~django.http.HttpRequest` in which the comment is being submitted:
150
.. method:: CommentModerator.allow(comment, content_object, request)
152
Should return ``True`` if the comment should be allowed to
153
post on the content object, and ``False`` otherwise (in which
154
case the comment will be immediately deleted).
156
.. method:: CommentModerator.email(comment, content_object, request)
158
If email notification of the new comment should be sent to
159
site staff or moderators, this method is responsible for
162
.. method:: CommentModerator.moderate(comment, content_object, request)
164
Should return ``True`` if the comment should be moderated (in
165
which case its ``is_public`` field will be set to ``False``
166
before saving), and ``False`` otherwise (in which case the
167
``is_public`` field will not be changed).
170
Registering models for moderation
171
---------------------------------
173
The moderation system, represented by
174
``django.contrib.comments.moderation.moderator`` is an instance of the class
175
:class:`Moderator`, which allows registration and "unregistration" of models
178
.. function:: moderator.register(model_or_iterable, moderation_class)
180
Takes two arguments: the first should be either a model class
181
or list of model classes, and the second should be a subclass
182
of ``CommentModerator``, and register the model or models to
183
be moderated using the options defined in the
184
``CommentModerator`` subclass. If any of the models are
185
already registered for moderation, the exception
186
:exc:`AlreadyModerated` will be raised.
188
.. function:: moderator.unregister(model_or_iterable)
190
Takes one argument: a model class or list of model classes,
191
and removes the model or models from the set of models which
192
are being moderated. If any of the models are not currently
193
being moderated, the exception
194
:exc:`NotModerated` will be raised.
197
Customizing the moderation system
198
---------------------------------
200
Most use cases will work easily with simple subclassing of
201
:class:`CommentModerator` and registration with the provided
202
:class:`Moderator` instance, but customization of global moderation behavior
203
can be achieved by subclassing :class:`Moderator` and instead registering
204
models with an instance of the subclass.
208
In addition to the :meth:`Moderator.register` and
209
:meth:`Moderator.unregister` methods detailed above, the following methods
210
on :class:`Moderator` can be overridden to achieve customized behavior:
214
Determines how moderation is set up globally. The base
216
:class:`Moderator` does this by
217
attaching listeners to the :data:`~django.contrib.comments.signals.comment_will_be_posted`
218
and :data:`~django.contrib.comments.signals.comment_was_posted` signals from the
221
.. method:: pre_save_moderation(sender, comment, request, **kwargs)
223
In the base implementation, applies all pre-save moderation
224
steps (such as determining whether the comment needs to be
225
deleted, or whether it needs to be marked as non-public or
228
.. method:: post_save_moderation(sender, comment, request, **kwargs)
230
In the base implementation, applies all post-save moderation
231
steps (currently this consists entirely of deleting comments
232
which were disallowed).