/docs/moderation.txt
Plain Text | 286 lines | 219 code | 67 blank | 0 comment | 0 complexity | a1acb2371a211f930688066e6accd776 MD5 | raw file
Possible License(s): BSD-3-Clause
- ==========================
- Generic comment moderation
- ==========================
- Django's bundled comments application is extremely useful on its own,
- but the amount of comment spam circulating on the Web today
- essentially makes it necessary to have some sort of automatic
- moderation system in place for any application which makes use of
- comments. To make this easier to handle in a consistent fashion,
- ``comment_utils`` provides a generic, extensible comment-moderation
- system which can be applied to any model or set of models which want
- to make use of Django's comment system.
- Overview
- ========
- The entire system is contained within ``comment_utils.moderation``,
- and uses a two-step process to enable moderation for any given model:
- 1. A subclass of ``comment_utils.moderation.CommentModerator`` is
- defined which specifies the moderation options the model wants to
- enable.
- 2. The model is registered with the moderation system, passing in the
- model class and the class which specifies its moderation options.
- A simple example is the best illustration of this. Suppose we have the
- following model, which would represent entries in a weblog::
- from django.db import models
-
- class Entry(models.Model):
- title = models.CharField(maxlength=250)
- body = models.TextField()
- pub_date = models.DateTimeField()
- enable_comments = models.BooleanField()
- Now, suppose that we want the following steps to be applied whenever a
- new comment is posted on an ``Entry``:
- 1. If the ``Entry``'s ``enable_comments`` field is ``False``, the
- comment will simply be disallowed (i.e., immediately deleted).
- 2. If the ``enable_comments`` field is ``True``, the comment will be
- allowed to save, but will first be submitted to an Akismet spam
- check and have its ``is_public`` field set to ``False`` if Akismet
- thinks the comment is spam.
- 3. Once the comment is saved, an email should be sent to site staff
- notifying them of the new comment.
- Accomplishing this is fairly straightforward and requires very little
- code::
- from comment_utils.moderation import CommentModerator, moderator
-
- class EntryModerator(CommentModerator):
- akismet = True
- email_notification = True
- enable_field = 'enable_comments'
-
- moderator.register(Entry, EntryModerator)
- The ``CommentModerator`` class pre-defines a number of useful
- moderation options which subclasses can enable or disable as desired,
- and ``moderator`` knows how to work with them to determine whether to
- allow a comment, whether to moderate a comment which will be allowed
- to post, and whether to email notifications of new comments.
- Built-in moderation options
- ---------------------------
- Most common comment-moderation needs can be handled by subclassing
- ``CommentModerator`` and changing the values of pre-defined
- attributes; the full range of built-in options is as follows::
- ``akismet``
- If ``True``, comments will be submitted to an Akismet spam
- check and, if Akismet thinks they're spam, will have their
- ``is_public`` field set to ``False`` before saving. If this is
- enabled, you will need to have the Python Akismet module
- installed, and you will need to add the setting
- ``AKISMET_API_KEY`` to your Django settings file; the value of
- this setting should be a valid Akismet API key. Default value
- is ``False``.
- ``auto_close_field``
- If this is set to the name of a ``DateField`` or
- ``DateTimeField`` on the model for which comments are being
- moderated, new comments for objects of that model will be
- disallowed (immediately deleted) when a certain number of days
- have passed after the date specified in that field. Must be
- used in conjunction with ``close_after``, which specifies the
- number of days past which comments should be
- disallowed. Default value is ``None``.
-
- ``auto_moderate_field``
- Like ``auto_close_field``, but instead of outright deleting
- new comments when the requisite number of days have elapsed,
- it will simply set the ``is_public`` field of new comments to
- ``False`` before saving them. Must be used in conjunction with
- ``moderate_after``, which specifies the number of days past
- which comments should be moderated. Default value is ``None``.
-
- ``close_after``
- If ``auto_close_field`` is used, this must specify the number
- of days past the value of the field specified by
- ``auto_close_field`` after which new comments for an object
- should be disallowed. Default value is ``None``.
-
- ``email_notification``
- If ``True``, any new comment on an object of this model which
- survives moderation (i.e., is not deleted) will generate an
- email to site staff. Default value is ``False``.
-
- ``enable_field``
- If this is set to the name of a ``BooleanField`` on the model
- for which comments are being moderated, new comments on
- objects of that model will be disallowed (immediately deleted)
- whenever the value of that field is ``False`` on the object
- the comment would be attached to. Default value is ``None``.
-
- ``moderate_after``
- If ``auto_moderate`` is used, this must specify the number of
- days past the value of the field specified by
- ``auto_moderate_field`` after which new comments for an object
- should be marked non-public. Default value is ``None``.
- Simply subclassing ``CommentModerator`` and changing the values of
- these options will automatically enable the various moderation methods
- for any models registered using the subclass.
- Adding custom moderation methods
- --------------------------------
- For situations where the built-in options listed above are not
- sufficient, subclasses of ``CommentModerator`` can also override the
- methods which actually perform the moderation, and apply any logic
- they desire. ``CommentModerator`` defines three methods which
- determine how moderation will take place; each method will be called
- by the moderation system and passed two arguments: ``comment``, which
- is the new comment being posted, and ``content_object``, which is the
- object the comment will be attached to::
- ``allow``
- Should return ``True`` if the comment should be allowed to
- post on the content object, and ``False`` otherwise (in which
- case the comment will be immediately deleted).
-
- ``email``
- If email notification of the new comment should be sent to
- site staff or moderators, this method is responsible for
- sending the email.
-
- ``moderate``
- Should return ``True`` if the comment should be moderated (in
- which case its ``is_public`` field will be set to ``False``
- before saving), and ``False`` otherwise (in which case the
- ``is_public`` field will not be changed).
- Built-in subclasses of ``CommentModerator``
- -------------------------------------------
- In order to make common cases simpler, and to provide examples of how
- ``CommentModerator`` can be adapted to various types of moderation,
- three subclasses are included which set up different moderation
- options::
- ``AkismetModerator``
- Applies an Akismet spam check to all new comments for the
- model on which it is used.
- ``AlwaysModerate``
- Forces all new comments for its model into moderation (by
- setting ``is_public=False``).
- ``ModerateFirstTimers``
- Automatically moderates all comments from anyone who has not
- previously had a comment approved, while allowing all other
- comments to skip moderation.
- Registering models for moderation
- ---------------------------------
- The moderation system, represented by
- ``comment_utils.moderation.moderator`` is an instance of the class
- ``comment_utils.moderation.Moderator``, which allows registration and
- "unregistration" of models via two methods::
- ``register``
- Takes two arguments: the first should be either a model class
- or list of model classes, and the second should be a subclass
- of ``CommentModerator``, and register the model or models to
- be moderated using the options defined in the
- ``CommentModerator`` subclass. If any of the models are
- already registered for moderation, the exception
- ``comment_utils.moderation.AlreadyModerated`` will be raised.
- ``unregister``
- Takes one argument: a model class or list of model classes,
- and removes the model or models from the set of models which
- are being moderated. If any of the models are not currently
- being moderated, the exception
- ``comment_utils.moderation.NotModerated`` will be raised.
- Customizing the moderation system
- ---------------------------------
- Most use cases will work easily with simple subclassing of
- ``CommentModerator`` and registration with the provided ``moderator``
- instance, but customization of global moderation behavior can be
- achieved by subclassing ``Moderator`` and instead registering models
- with an instance of the subclass.
- In addition to the ``register`` and ``unregister`` methods detailed
- above, the following methods on ``Moderator`` can be overridden to
- achieve customized behavior::
- ``connect``
- Determines how moderation is set up globally. The base
- implementation in ``Moderator`` does this by attaching
- listeners to the ``pre_save`` and ``post_save`` signals from
- the comment models.
- ``pre_save_moderation``
- In the base implementation, applies all pre-save moderation
- steps (such as determining whether the comment needs to be
- deleted, or whether it needs to be marked as non-public or
- generate an email).
- ``post_save_moderation``
- In the base implementation, applies all post-save moderation
- steps (currently this consists entirely of deleting comments
- which were disallowed).
- Automatically deleting non-public comments
- ------------------------------------------
- In order to save the hassle of manually deleting spam or
- otherwise-non-public comments on a regular basis, a script is included
- -- ``bin/delete_spam_comments.py`` -- which is intended to be used as
- a cron job, and which will automatically delete non-public comments
- based on criteria you provide to it.
- **Required arguments**
- ``-s``, ``--settings``
- Specifies the Django settings module to use.
- **Optional arguments**
- ``-a`` ``--age``
- An age cutoff, in days, beyond which non-public comments will be
- deleted. for example, when using ``--age=7`` any non-public
- comment older than 7 days will be deleted. Defaults to 14 if not
- specified.
- ``-d``, ``--dry-run``
- Prints the number of comments which would have been deleted, but
- does not actually delete them.
- ``-t``, ``--type``
- The type of comment to delete; ``--type=free`` will delete
- instance of ``FreeComment``, ``--type=registered`` will delete
- instances of ``Comment``. Defaults to "free" if not specified.
- ``-v``, ``--verbose``
- If supplied, the script will run verbosely, printing a description
- of each comment as it is deleted. Regardless of the value of this
- argument, the script will print the total number of deleted
- comments once it is finished.
- So, for example, the script could be used like so::
- ``python /path/to/comment_utils/bin/delete_spam_comments.py --settings=mysite.settings --age=7 --type=registered
- This would delete every non-public ``Comment`` in the ``mysite``
- database older than 7 days.