custom.txt 7.2 KB

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