custom.txt 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. ==================================
  2. Customizing the comments framework
  3. ==================================
  4. .. currentmodule:: django.contrib.comments
  5. .. warning::
  6. Django's comment framework has been deprecated and is no longer supported.
  7. Most users will be better served with a custom solution, or a hosted
  8. product like Disqus__.
  9. The code formerly known as ``django.contrib.comments`` is `still available
  10. in an external repository`__.
  11. __ https://disqus.com/
  12. __ https://github.com/django/django-contrib-comments
  13. If the built-in comment framework doesn't quite fit your needs, you can extend
  14. the comment app's behavior to add custom data and logic. The comments framework
  15. lets you extend the built-in comment model, the built-in comment form, and the
  16. various comment views.
  17. The :setting:`COMMENTS_APP` setting is where this customization begins. Set
  18. :setting:`COMMENTS_APP` to the name of the app you'd like to use to provide
  19. custom behavior. You'll use the same syntax as you'd use for
  20. :setting:`INSTALLED_APPS`, and the app given must also be in the
  21. :setting:`INSTALLED_APPS` list.
  22. For example, if you wanted to use an app named ``my_comment_app``, your
  23. settings file would contain::
  24. INSTALLED_APPS = [
  25. ...
  26. 'my_comment_app',
  27. ...
  28. ]
  29. COMMENTS_APP = 'my_comment_app'
  30. The app named in :setting:`COMMENTS_APP` provides its custom behavior by
  31. defining some module-level functions in the app's ``__init__.py``. The
  32. :ref:`complete list of these functions <custom-comment-app-api>` can be found
  33. below, but first let's look at a quick example.
  34. An example custom comments app
  35. ==============================
  36. One of the most common types of customization is modifying the set of fields
  37. provided on the built-in comment model. For example, some sites that allow
  38. comments want the commentator to provide a title for their comment; the built-in
  39. comment model has no field for that title.
  40. To make this kind of customization, we'll need to do three things:
  41. #. Create a custom comment :class:`~django.db.models.Model` that adds on the
  42. "title" field.
  43. #. Create a custom comment :class:`~django.forms.Form` that also adds this
  44. "title" field.
  45. #. Inform Django of these objects by defining a few functions in a
  46. custom :setting:`COMMENTS_APP`.
  47. So, carrying on the example above, we're dealing with a typical app structure in
  48. the ``my_comment_app`` directory::
  49. my_comment_app/
  50. __init__.py
  51. models.py
  52. forms.py
  53. In the ``models.py`` we'll define a ``CommentWithTitle`` model::
  54. from django.db import models
  55. from django.contrib.comments.models import Comment
  56. class CommentWithTitle(Comment):
  57. title = models.CharField(max_length=300)
  58. Most custom comment models will subclass the
  59. :class:`~django.contrib.comments.models.Comment` model. However,
  60. if you want to substantially remove or change the fields available in the
  61. :class:`~django.contrib.comments.models.Comment` model, but don't want to
  62. rewrite the templates, you could try subclassing from
  63. ``BaseCommentAbstractModel``.
  64. Next, we'll define a custom comment form in ``forms.py``. This is a little more
  65. tricky: we have to both create a form and override
  66. ``CommentForm.get_comment_model()`` and
  67. ``CommentForm.get_comment_create_data()`` to return deal with our custom title
  68. field::
  69. from django import forms
  70. from django.contrib.comments.forms import CommentForm
  71. from my_comment_app.models import CommentWithTitle
  72. class CommentFormWithTitle(CommentForm):
  73. title = forms.CharField(max_length=300)
  74. def get_comment_model(self):
  75. # Use our custom comment model instead of the built-in one.
  76. return CommentWithTitle
  77. def get_comment_create_data(self):
  78. # Use the data of the superclass, and add in the title field
  79. data = super(CommentFormWithTitle, self).get_comment_create_data()
  80. data['title'] = self.cleaned_data['title']
  81. return data
  82. Django provides a couple of "helper" classes to make writing certain types of
  83. custom comment forms easier; see :mod:`django.contrib.comments.forms` for
  84. more.
  85. Finally, we'll define a couple of methods in ``my_comment_app/__init__.py`` to
  86. point Django at these classes we've created::
  87. from my_comment_app.models import CommentWithTitle
  88. from my_comment_app.forms import CommentFormWithTitle
  89. def get_model():
  90. return CommentWithTitle
  91. def get_form():
  92. return CommentFormWithTitle
  93. .. warning::
  94. Be careful not to create cyclic imports in your custom comments app.
  95. If you feel your comment configuration isn't being used as defined --
  96. for example, if your comment moderation policy isn't being applied --
  97. you may have a cyclic import problem.
  98. If you are having unexplained problems with comments behavior, check
  99. if your custom comments application imports (even indirectly)
  100. any module that itself imports Django's comments module.
  101. The above process should take care of most common situations. For more
  102. advanced usage, there are additional methods you can define. Those are
  103. explained in the next section.
  104. .. _custom-comment-app-api:
  105. Custom comment app API
  106. ======================
  107. The :mod:`django.contrib.comments` app defines the following methods; any
  108. custom comment app must define at least one of them. All are optional,
  109. however.
  110. .. function:: get_model()
  111. Return the :class:`~django.db.models.Model` class to use for comments. This
  112. model should inherit from
  113. ``django.contrib.comments.models.BaseCommentAbstractModel``, which
  114. defines necessary core fields.
  115. The default implementation returns
  116. :class:`django.contrib.comments.models.Comment`.
  117. .. function:: get_form()
  118. Return the :class:`~django.forms.Form` class you want to use for
  119. creating, validating, and saving your comment model. Your custom
  120. comment form should accept an additional first argument,
  121. ``target_object``, which is the object the comment will be
  122. attached to.
  123. The default implementation returns
  124. :class:`django.contrib.comments.forms.CommentForm`.
  125. .. note::
  126. The default comment form also includes a number of unobtrusive
  127. spam-prevention features (see
  128. :ref:`notes-on-the-comment-form`). If replacing it with your
  129. own form, you may want to look at the source code for the
  130. built-in form and consider incorporating similar features.
  131. .. function:: get_form_target()
  132. Return the URL for POSTing comments. This will be the ``<form action>``
  133. attribute when rendering your comment form.
  134. The default implementation returns a reverse-resolved URL pointing
  135. to the ``post_comment()`` view.
  136. .. note::
  137. If you provide a custom comment model and/or form, but you
  138. want to use the default ``post_comment()`` view, you will
  139. need to be aware that it requires the model and form to have
  140. certain additional attributes and methods: see the
  141. ``django.contrib.comments.views.post_comment()`` view for details.
  142. .. function:: get_flag_url()
  143. Return the URL for the "flag this comment" view.
  144. The default implementation returns a reverse-resolved URL pointing
  145. to the ``django.contrib.comments.views.moderation.flag()`` view.
  146. .. function:: get_delete_url()
  147. Return the URL for the "delete this comment" view.
  148. The default implementation returns a reverse-resolved URL pointing
  149. to the ``django.contrib.comments.views.moderation.delete()`` view.
  150. .. function:: get_approve_url()
  151. Return the URL for the "approve this comment from moderation" view.
  152. The default implementation returns a reverse-resolved URL pointing
  153. to the ``django.contrib.comments.views.moderation.approve()`` view.