moderation.txt 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. ==========================
  2. Generic comment moderation
  3. ==========================
  4. .. module:: django.contrib.comments.moderation
  5. :synopsis: Support for automatic comment moderation.
  6. .. warning::
  7. Django's comment framework has been deprecated and is no longer supported.
  8. Most users will be better served with a custom solution, or a hosted
  9. product like Disqus__.
  10. The code formerly known as ``django.contrib.comments`` is `still available
  11. in an external repository`__.
  12. __ https://disqus.com/
  13. __ https://github.com/django/django-contrib-comments
  14. Django's bundled comments application is extremely useful on its own,
  15. but the amount of comment spam circulating on the Web today
  16. essentially makes it necessary to have some sort of automatic
  17. moderation system in place for any application which makes use of
  18. comments. To make this easier to handle in a consistent fashion,
  19. ``django.contrib.comments.moderation`` provides a generic, extensible
  20. comment-moderation system which can be applied to any model or set of
  21. models which want to make use of Django's comment system.
  22. Overview
  23. ========
  24. The entire system is contained within ``django.contrib.comments.moderation``,
  25. 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
  28. enable.
  29. 2. The model is registered with the moderation system, passing in the
  30. model class and the class which specifies its moderation options.
  31. A simple example is the best illustration of this. Suppose we have the
  32. following model, which would represent entries in a Weblog::
  33. from django.db import models
  34. class Entry(models.Model):
  35. title = models.CharField(maxlength=250)
  36. body = models.TextField()
  37. pub_date = models.DateField()
  38. enable_comments = models.BooleanField()
  39. Now, suppose that we want the following steps to be applied whenever a
  40. new comment is posted on an ``Entry``:
  41. 1. If the ``Entry``’s ``enable_comments`` field is ``False``, the
  42. comment will simply be disallowed (i.e., immediately deleted).
  43. 2. If the ``enable_comments`` field is ``True``, the comment will be
  44. allowed to save.
  45. 3. Once the comment is saved, an email should be sent to site staff
  46. notifying them of the new comment.
  47. Accomplishing this is fairly straightforward and requires very little
  48. code::
  49. from django.contrib.comments.moderation import CommentModerator, moderator
  50. class EntryModerator(CommentModerator):
  51. email_notification = True
  52. enable_field = 'enable_comments'
  53. moderator.register(Entry, EntryModerator)
  54. The :class:`CommentModerator` class pre-defines a number of useful moderation
  55. options which subclasses can enable or disable as desired, and ``moderator``
  56. knows how to work with them to determine whether to allow a comment, whether
  57. to moderate a comment which will be allowed to post, and whether to email
  58. notifications of new comments.
  59. Built-in moderation options
  60. ---------------------------
  61. .. class:: CommentModerator
  62. Most common comment-moderation needs can be handled by subclassing
  63. :class:`CommentModerator` and
  64. changing the values of pre-defined attributes; the full range of built-in
  65. options is as follows.
  66. .. attribute:: auto_close_field
  67. If this is set to the name of a
  68. :class:`~django.db.models.DateField` or
  69. :class:`~django.db.models.DateTimeField` on the model for which
  70. comments are being moderated, new comments for objects of that model
  71. will be disallowed (immediately deleted) when a certain number of days
  72. have passed after the date specified in that field. Must be
  73. used in conjunction with :attr:`close_after`, which specifies the
  74. number of days past which comments should be
  75. disallowed. Default value is ``None``.
  76. .. attribute:: auto_moderate_field
  77. Like :attr:`auto_close_field`, but instead of outright deleting
  78. new comments when the requisite number of days have elapsed,
  79. it will simply set the ``is_public`` field of new comments to
  80. ``False`` before saving them. Must be used in conjunction with
  81. :attr:`moderate_after`, which specifies the number of days past
  82. which comments should be moderated. Default value is ``None``.
  83. .. attribute:: close_after
  84. If :attr:`auto_close_field` is used, this must specify the number
  85. of days past the value of the field specified by
  86. :attr:`auto_close_field` after which new comments for an object
  87. should be disallowed. Allowed values are ``None``, 0 (which disallows
  88. comments immediately), or any positive integer. Default value is
  89. ``None``.
  90. .. attribute:: email_notification
  91. If ``True``, any new comment on an object of this model which
  92. survives moderation (i.e., is not deleted) will generate an
  93. email to site staff. Default value is ``False``.
  94. .. attribute:: enable_field
  95. If this is set to the name of a
  96. :class:`~django.db.models.BooleanField` on the model
  97. for which comments are being moderated, new comments on
  98. objects of that model will be disallowed (immediately deleted)
  99. whenever the value of that field is ``False`` on the object
  100. the comment would be attached to. Default value is ``None``.
  101. .. attribute:: moderate_after
  102. If :attr:`auto_moderate_field` is used, this must specify the number
  103. of days past the value of the field specified by
  104. :attr:`auto_moderate_field` after which new comments for an object
  105. should be marked non-public. Allowed values are ``None``, 0 (which
  106. moderates comments immediately), or any positive integer. Default
  107. value is ``None``.
  108. Simply subclassing :class:`CommentModerator` and changing the values of these
  109. options will automatically enable the various moderation methods for any
  110. models registered using the subclass.
  111. Adding custom moderation methods
  112. --------------------------------
  113. For situations where the built-in options listed above are not
  114. sufficient, subclasses of :class:`CommentModerator` can also override
  115. the methods which actually perform the moderation, and apply any logic
  116. they desire. :class:`CommentModerator` defines three methods which
  117. determine how moderation will take place; each method will be called
  118. by the moderation system and passed two arguments: ``comment``, which
  119. is the new comment being posted, ``content_object``, which is the
  120. object the comment will be attached to, and ``request``, which is the
  121. :class:`~django.http.HttpRequest` in which the comment is being submitted:
  122. .. method:: CommentModerator.allow(comment, content_object, request)
  123. Should return ``True`` if the comment should be allowed to
  124. post on the content object, and ``False`` otherwise (in which
  125. case the comment will be immediately deleted).
  126. .. method:: CommentModerator.email(comment, content_object, request)
  127. If email notification of the new comment should be sent to
  128. site staff or moderators, this method is responsible for
  129. sending the email.
  130. .. method:: CommentModerator.moderate(comment, content_object, request)
  131. Should return ``True`` if the comment should be moderated (in
  132. which case its ``is_public`` field will be set to ``False``
  133. before saving), and ``False`` otherwise (in which case the
  134. ``is_public`` field will not be changed).
  135. Registering models for moderation
  136. ---------------------------------
  137. The moderation system, represented by
  138. ``django.contrib.comments.moderation.moderator`` is an instance of the class
  139. :class:`Moderator`, which allows registration and "unregistration" of models
  140. via two methods:
  141. .. function:: moderator.register(model_or_iterable, moderation_class)
  142. Takes two arguments: the first should be either a model class
  143. or list of model classes, and the second should be a subclass
  144. of ``CommentModerator``, and register the model or models to
  145. be moderated using the options defined in the
  146. ``CommentModerator`` subclass. If any of the models are
  147. already registered for moderation, the exception
  148. ``AlreadyModerated`` will be raised.
  149. .. function:: moderator.unregister(model_or_iterable)
  150. Takes one argument: a model class or list of model classes,
  151. and removes the model or models from the set of models which
  152. are being moderated. If any of the models are not currently
  153. being moderated, the exception ``NotModerated`` will be raised.
  154. Customizing the moderation system
  155. ---------------------------------
  156. Most use cases will work easily with simple subclassing of
  157. :class:`CommentModerator` and registration with the provided
  158. :class:`Moderator` instance, but customization of global moderation behavior
  159. can be achieved by subclassing :class:`Moderator` and instead registering
  160. models with an instance of the subclass.
  161. .. class:: Moderator
  162. In addition to the :func:`moderator.register` and
  163. :func:`moderator.unregister` methods detailed above, the following methods
  164. on :class:`Moderator` can be overridden to achieve customized behavior:
  165. .. method:: connect
  166. Determines how moderation is set up globally. The base
  167. implementation in
  168. :class:`Moderator` does this by
  169. attaching listeners to the :data:`~django.contrib.comments.signals.comment_will_be_posted`
  170. and :data:`~django.contrib.comments.signals.comment_was_posted` signals from the
  171. comment models.
  172. .. method:: pre_save_moderation(sender, comment, request, **kwargs)
  173. In the base implementation, applies all pre-save moderation
  174. steps (such as determining whether the comment needs to be
  175. deleted, or whether it needs to be marked as non-public or
  176. generate an email).
  177. .. method:: post_save_moderation(sender, comment, request, **kwargs)
  178. In the base implementation, applies all post-save moderation
  179. steps (currently this consists entirely of deleting comments
  180. which were disallowed).