123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- .. highlightlang:: html+django
- ===========================================
- Example of using the built-in comments app
- ===========================================
- .. warning::
- Django's comment framework has been deprecated and is no longer supported.
- Most users will be better served with a custom solution, or a hosted
- product like Disqus__.
- The code formerly known as ``django.contrib.comments`` is `still available
- in an external repository`__.
- __ https://disqus.com/
- __ https://github.com/django/django-contrib-comments
- 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's 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 its functionality. So
- just like all other custom template tag libraries::
- {% load comments %}
- Next, let's 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>
- 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.
- Using this tag is very similar to the :ttag:`get_comment_count` tag. We
- need to remember that :ttag:`get_comment_list` returns a list of comments
- and hence we 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. Its 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">
- {% csrf_token %}
- {{ form }}
- <tr>
- <td colspan="2">
- <input type="submit" name="submit" value="Post">
- <input type="submit" name="preview" 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 built-in ``LatestCommentFeed``. Just
- enable it in your project's ``urls.py``:
- .. code-block:: python
- from django.conf.urls import patterns
- from django.contrib.comments.feeds import LatestCommentFeed
- urlpatterns = patterns('',
- # ...
- (r'^feeds/latest/$', LatestCommentFeed()),
- # ...
- )
- 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
- built-in 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 ``CommentModerator`` and
- register it with the moderation features we want. Let's 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``.
|