| | 1 | .. _ref-contrib-comments-example: |
| | 2 | |
| | 3 | =========================================== |
| | 4 | Example of using the in-built comments app |
| | 5 | =========================================== |
| | 6 | |
| | 7 | #. Follow the first three steps of the quick start guide in the |
| | 8 | :ref:`documentation <ref-contrib-comments-index>`. |
| | 9 | |
| | 10 | #. Now suppose, you have an app (``blog``) with a model (``Post``) |
| | 11 | to which you want to attach comments. Let us also suppose that |
| | 12 | you have a template called ``blog_detail.html`` where you want |
| | 13 | to display the comments list and comment form. |
| | 14 | |
| | 15 | #. First, we should load the ``comment`` template tags in the |
| | 16 | ``blog_detail.html`` so that we can use it's functionality. So |
| | 17 | just like all other custom template tag libraries:: |
| | 18 | |
| | 19 | {% load comments %} |
| | 20 | |
| | 21 | #. Next, let us add the number of comments attached to the particular |
| | 22 | model instance of ``Post``. For this we assume that a context |
| | 23 | variable ``object_pk`` is present which gives the ``id`` of the |
| | 24 | instance of ``Post``. |
| | 25 | |
| | 26 | The usage of the ``get_comment_count`` tag is like below:: |
| | 27 | |
| | 28 | {% get_comment_count for blog.post object_pk as comment_count %} |
| | 29 | <p>{{ comment_count }} comments have been posted.</p> |
| | 30 | |
| | 31 | If you have the instance (say ``entry``) of the model (``Post``) |
| | 32 | available in the context, then you can refer to it directly:: |
| | 33 | |
| | 34 | {% get_comment_count for entry as comment_count %} |
| | 35 | <p>{{ comment_count }} comments have been posted.</p> |
| | 36 | |
| | 37 | #. To get a list of comments, we make use of the ``get_comment_list`` tag. |
| | 38 | This tag's usage is very similar to the ``get_comment_count`` tag. We |
| | 39 | need to remember that the ``get_comment_list`` returns a list of comments |
| | 40 | and hence we will have to iterate through them to display them:: |
| | 41 | |
| | 42 | {% get_comment_list for blog.post object_pk as comment_list %} |
| | 43 | {% for comment in comment_list %} |
| | 44 | <p>Posted by: {{ comment.user_name }} on {{ comment.submit_date }}</p> |
| | 45 | ... |
| | 46 | <p>Comment: {{ comment.comment }}</p> |
| | 47 | ... |
| | 48 | {% endfor %} |
| | 49 | |
| | 50 | #. Finally, we display the comment form, enabling users to enter their comments. |
| | 51 | There are two ways of doing so. The first is when you want to display the |
| | 52 | comments template available under your ``comments/form.html``. The other method |
| | 53 | gives you a chance to customize the form. |
| | 54 | |
| | 55 | The first method makes use of the ``render_comment_form`` tag. It's usage too is |
| | 56 | similar to the other two tags we have discussed above:: |
| | 57 | |
| | 58 | {% render_comment_form for entry %} |
| | 59 | |
| | 60 | It looks for the ``form.html`` under the following directories (for our example):: |
| | 61 | |
| | 62 | comments/blog/post/form.html |
| | 63 | comments/blog/form.html |
| | 64 | comments/form.html |
| | 65 | |
| | 66 | Since we customize the form in the second method, we make use of another tag called |
| | 67 | ``get_comment_target``. This tag on rendering gives the URL where the comment form is |
| | 68 | posted. Without any :ref:`customization <ref-contrib-comments-custom>`, ``get_comment_target`` |
| | 69 | evaluates to ``/comments/post/``. We use this tag in the form's ``action`` attribute. The |
| | 70 | ``get_comment_form`` tag renders a ``form`` for a model instance by creating a context |
| | 71 | variable. One can iterate over the ``form`` object to get individual fields. This gives |
| | 72 | you fine-grain control over the form:: |
| | 73 | |
| | 74 | {% for field in form %} |
| | 75 | {% ifequal field.name "comment" %} |
| | 76 | <!-- Customize the "comment" field, say, make CSS changes --> |
| | 77 | ... |
| | 78 | {% endfor %} |
| | 79 | |
| | 80 | But let's look at a simple example:: |
| | 81 | |
| | 82 | {% get_comment_form for entry as form %} |
| | 83 | <!-- A context variable called form is created with the necessary hidden fields, |
| | 84 | timestamps and security hashes --> |
| | 85 | <table> |
| | 86 | <form action="{% comment_form_target %}" method="POST"> |
| | 87 | {{ form }} |
| | 88 | <tr> |
| | 89 | <td></td> |
| | 90 | <td><input type="submit" name="preview" class="submit-post" value="Preview"></td> |
| | 91 | </tr> |
| | 92 | </form> |
| | 93 | </table> |
| | 94 | |
| | 95 | #. If you want your users to be able to flag comments (say for profanity), you can just direct them |
| | 96 | (by placing a link in your comment list) to ``/flag/{{ comment.id }}/``. Similarly, a user with |
| | 97 | requisite permissions (``"Can moderate comments"``) can approve and delete comments. This can |
| | 98 | also be done through the ``admin`` as you'll see later. You might also want to customize the |
| | 99 | following templates: |
| | 100 | |
| | 101 | * ``flag.html`` |
| | 102 | * ``flagged.html`` |
| | 103 | * ``approve.html`` |
| | 104 | * ``approved.html`` |
| | 105 | * ``delete.html`` |
| | 106 | * ``deleted.html`` |
| | 107 | |
| | 108 | found under the directory structure we saw for ``form.html``. |
| | 109 | |
| | 110 | #. Suppose you want to export a :ref:`feed <ref-contrib-syndication>` of the latest comments, |
| | 111 | you can use the in-built :class:`LatestCommentFeed`. Just enable it in your project's ``urls.py``:: |
| | 112 | |
| | 113 | from django.conf.urls.defaults import * |
| | 114 | from django.contrib.comments.feeds import LatestCommentFeed |
| | 115 | |
| | 116 | feeds = { |
| | 117 | 'latest': LatestCommentFeed, |
| | 118 | } |
| | 119 | |
| | 120 | urlpatterns = patterns('', |
| | 121 | # ... |
| | 122 | (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', |
| | 123 | {'feed_dict': feeds}), |
| | 124 | # ... |
| | 125 | ) |
| | 126 | |
| | 127 | Now you should have the latest comment feeds being served off ``/feeds/latest/``. |
| | 128 | |
| | 129 | #. Now that we have the comments framework working, we might want to have some moderation setup |
| | 130 | to administer the comments. The comments framework comes in-built with |
| | 131 | :ref:`generic comment moderation <ref-contrib-comments-moderation>`. The comment moderation |
| | 132 | has the following features (all of which or only certain can be enabled): |
| | 133 | |
| | 134 | * Enable comments for a particular model instance. |
| | 135 | * Close comments after a particular (user-defined) number of days. |
| | 136 | * Email new comments to the site-staff. |
| | 137 | |
| | 138 | #. To enable comment moderation, we subclass the :class:`CommentModerator` and register it with |
| | 139 | the moderation features we want. Let us suppose we want to close comments after 7 days of |
| | 140 | posting and also send out an email to the site staff. In ``blog/models.py``, we register a |
| | 141 | comment moderator in the following way:: |
| | 142 | |
| | 143 | from django.contrib.comments.moderation import CommentModerator, moderator |
| | 144 | from django.db import models |
| | 145 | |
| | 146 | class Post(models.Model): |
| | 147 | title = models.CharField(max_length = 255) |
| | 148 | content = models.TextField() |
| | 149 | posted_date = models.DateTimeField() |
| | 150 | |
| | 151 | class PostModerator(CommentModerator): |
| | 152 | email_notification = True |
| | 153 | auto_close_field = 'posted_date' |
| | 154 | # Close the comments after 7 days. |
| | 155 | close_after = 7 |
| | 156 | |
| | 157 | moderator.register(Post, PostModerator) |
| | 158 | |
| | 159 | #. The generic comment moderation also has the facility to remove comments. These comments can |
| | 160 | then be moderated by any user who has access to the ``admin`` site and the |
| | 161 | ``Can moderate comments`` permission (can be set under the ``Users`` page in the ``admin``). |
| | 162 | |
| | 163 | #. The moderator can ``Flag``, ``Approve`` or ``Remove`` comments using the ``Action`` drop-down |
| | 164 | in the ``admin`` under the ``Comments`` page. |
| | 165 | |
| | 166 | .. note:: |
| | 167 | |
| | 168 | Only a super-user will be able to delete comments from the database. ``Remove Comments`` |
| | 169 | only sets the ``is_public`` attribute to ``False``. |