| .. highlightlang:: html+django |
| |
| =========================================== |
| Example of using the in-built comments app |
| =========================================== |
| |
| Follow the first three steps of the quick start guide in the |
| :doc:`documentation </ref/contrib/comments/index>`. |
| |
| Now suppose, you have an app (``blog``) with a model (``Post``) |
| to which you want to attach comments. Let us also suppose that |
| you have a template called ``blog_detail.html`` where you want |
| to display the comments list and comment form. |
| |
| Template |
| ======== |
| |
| First, we should load the ``comment`` template tags in the |
| ``blog_detail.html`` so that we can use it's functionality. So |
| just like all other custom template tag libraries:: |
| |
| {% load comments %} |
| |
| Next, let us add the number of comments attached to the particular |
| model instance of ``Post``. For this we assume that a context |
| variable ``object_pk`` is present which gives the ``id`` of the |
| instance of ``Post``. |
| |
| The usage of the :ttag:`get_comment_count` tag is like below:: |
| |
| {% get_comment_count for blog.post object_pk as comment_count %} |
| <p>{{ comment_count }} comments have been posted.</p> |
| |
| If you have the instance (say ``entry``) of the model (``Post``) |
| available in the context, then you can refer to it directly:: |
| |
| {% get_comment_count for entry as comment_count %} |
| <p>{{ comment_count }} comments have been posted.</p> |
| |
| .. versionadded:: 1.2 |
| |
| Next, we can use the :ttag:`render_comment_list` tag, to render all comments |
| to the given instance (``entry``) by using the ``comments/list.html`` template. |
| |
| {% render_comment_list for entry %} |
| |
| Django will will look for the ``list.html`` under the following directories |
| (for our example):: |
| |
| comments/blog/post/list.html |
| comments/blog/list.html |
| comments/list.html |
| |
| To get a list of comments, we make use of the :ttag:`get_comment_list` tag. |
| This tag's usage is very similar to the :ttag:`get_comment_count` tag. We |
| need to remember that the :ttag:`get_comment_list` returns a list of comments |
| and hence we will have to iterate through them to display them:: |
| |
| {% get_comment_list for blog.post object_pk as comment_list %} |
| {% for comment in comment_list %} |
| <p>Posted by: {{ comment.user_name }} on {{ comment.submit_date }}</p> |
| ... |
| <p>Comment: {{ comment.comment }}</p> |
| ... |
| {% endfor %} |
| |
| Finally, we display the comment form, enabling users to enter their |
| comments. There are two ways of doing so. The first is when you want to |
| display the comments template available under your ``comments/form.html``. |
| The other method gives you a chance to customize the form. |
| |
| The first method makes use of the :ttag:`render_comment_form` tag. It's usage |
| too is similar to the other three tags we have discussed above:: |
| |
| {% render_comment_form for entry %} |
| |
| It looks for the ``form.html`` under the following directories |
| (for our example):: |
| |
| comments/blog/post/form.html |
| comments/blog/form.html |
| comments/form.html |
| |
| Since we customize the form in the second method, we make use of another |
| tag called :ttag:`comment_form_target`. This tag on rendering gives the URL |
| where the comment form is posted. Without any :doc:`customization |
| </ref/contrib/comments/custom>`, :ttag:`comment_form_target` evaluates to |
| ``/comments/post/``. We use this tag in the form's ``action`` attribute. |
| |
| The :ttag:`get_comment_form` tag renders a ``form`` for a model instance by |
| creating a context variable. One can iterate over the ``form`` object to |
| get individual fields. This gives you fine-grain control over the form:: |
| |
| {% for field in form %} |
| {% ifequal field.name "comment" %} |
| <!-- Customize the "comment" field, say, make CSS changes --> |
| ... |
| {% endfor %} |
| |
| But let's look at a simple example:: |
| |
| {% get_comment_form for entry as form %} |
| <!-- A context variable called form is created with the necessary hidden |
| fields, timestamps and security hashes --> |
| <table> |
| <form action="{% comment_form_target %}" method="post"> |
| {{ form }} |
| <tr> |
| <td></td> |
| <td><input type="submit" name="preview" class="submit-post" value="Preview"></td> |
| </tr> |
| </form> |
| </table> |
| |
| Flagging |
| ======== |
| |
| If you want your users to be able to flag comments (say for profanity), you |
| can just direct them (by placing a link in your comment list) to ``/flag/{{ |
| comment.id }}/``. Similarly, a user with requisite permissions (``"Can |
| moderate comments"``) can approve and delete comments. This can also be |
| done through the ``admin`` as you'll see later. You might also want to |
| customize the following templates: |
| |
| * ``flag.html`` |
| * ``flagged.html`` |
| * ``approve.html`` |
| * ``approved.html`` |
| * ``delete.html`` |
| * ``deleted.html`` |
| |
| found under the directory structure we saw for ``form.html``. |
| |
| Feeds |
| ===== |
| |
| Suppose you want to export a :doc:`feed </ref/contrib/syndication>` of the |
| latest comments, you can use the in-built :class:`LatestCommentFeed`. Just |
| enable it in your project's ``urls.py``: |
| |
| .. code-block:: python |
| |
| from django.conf.urls.defaults import * |
| from django.contrib.comments.feeds import LatestCommentFeed |
| |
| feeds = { |
| 'latest': LatestCommentFeed, |
| } |
| |
| urlpatterns = patterns('', |
| # ... |
| (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', |
| {'feed_dict': feeds}), |
| # ... |
| ) |
| |
| Now you should have the latest comment feeds being served off ``/feeds/latest/``. |
| |
| Moderation |
| ========== |
| |
| Now that we have the comments framework working, we might want to have some |
| moderation setup to administer the comments. The comments framework comes |
| in-built with :doc:`generic comment moderation |
| </ref/contrib/comments/moderation>`. The comment moderation has the following |
| features (all of which or only certain can be enabled): |
| |
| * Enable comments for a particular model instance. |
| * Close comments after a particular (user-defined) number of days. |
| * Email new comments to the site-staff. |
| |
| To enable comment moderation, we subclass the :class:`CommentModerator` and |
| register it with the moderation features we want. Let us suppose we want to |
| close comments after 7 days of posting and also send out an email to the |
| site staff. In ``blog/models.py``, we register a comment moderator in the |
| following way: |
| |
| .. code-block:: python |
| |
| from django.contrib.comments.moderation import CommentModerator, moderator |
| from django.db import models |
| |
| class Post(models.Model): |
| title = models.CharField(max_length = 255) |
| content = models.TextField() |
| posted_date = models.DateTimeField() |
| |
| class PostModerator(CommentModerator): |
| email_notification = True |
| auto_close_field = 'posted_date' |
| # Close the comments after 7 days. |
| close_after = 7 |
| |
| moderator.register(Post, PostModerator) |
| |
| The generic comment moderation also has the facility to remove comments. |
| These comments can then be moderated by any user who has access to the |
| ``admin`` site and the ``Can moderate comments`` permission (can be set |
| under the ``Users`` page in the ``admin``). |
| |
| The moderator can ``Flag``, ``Approve`` or ``Remove`` comments using the |
| ``Action`` drop-down in the ``admin`` under the ``Comments`` page. |
| |
| .. note:: |
| |
| Only a super-user will be able to delete comments from the database. |
| ``Remove Comments`` only sets the ``is_public`` attribute to |
| ``False``. |