Refactored Django's comment system.

Much of this work was done by Thejaswi Puthraya as part of Google's Summer of Code project; much thanks to him for the work, and to them for the program.

This is a backwards-incompatible change; see the upgrading guide in docs/ref/contrib/comments/upgrade.txt for instructions if you were using the old comments system.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8557 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2008-08-25 22:14:22 +00:00
parent b46e736c9a
commit cba91997a2
49 changed files with 2410 additions and 1148 deletions

View file

@ -62,7 +62,7 @@ ins { font-weight: bold; text-decoration: none; }
/*** lists ***/
ul { padding-left:30px; }
ol { padding-left:30px; }
ol.arabic { list-style-type: decimal; }
ol.arabic li { list-style-type: decimal; }
ul li { list-style-type:square; margin-bottom:.4em; }
ol li { margin-bottom: .4em; }
ul ul { padding-left:1.2em; }

View file

@ -72,10 +72,16 @@ Using Django
And more:
---------
:ref:`topics-auth` ... :ref:`topics-cache` ... :ref:`topics-email` ...
:ref:`topics-files` ... :ref:`topics-i18n` ... :ref:`topics-install` ...
:ref:`topics-pagination` ... :ref:`topics-serialization` ...
:ref:`topics-settings` ... :ref:`topics-testing`
* :ref:`topics-auth`
* :ref:`topics-cache`
* :ref:`topics-email`
* :ref:`topics-files`
* :ref:`topics-i18n`
* :ref:`topics-install`
* :ref:`topics-pagination`
* :ref:`topics-serialization`
* :ref:`topics-settings`
* :ref:`topics-testing`
Add-on ("contrib") applications
===============================
@ -95,11 +101,16 @@ Add-on ("contrib") applications
And more:
---------
:ref:`ref-contrib-contenttypes` ... :ref:`ref-contrib-csrf` ...
:ref:`ref-contrib-databrowse` ... :ref:`ref-contrib-flatpages` ...
:ref:`ref-contrib-humanize` ... :ref:`ref-contrib-redirects` ...
:ref:`ref-contrib-sitemaps` ... :ref:`ref-contrib-sites` ...
:ref:`ref-contrib-webdesign`
* :ref:`ref-contrib-comments-index`
* :ref:`ref-contrib-contenttypes`
* :ref:`ref-contrib-csrf`
* :ref:`ref-contrib-databrowse`
* :ref:`ref-contrib-flatpages`
* :ref:`ref-contrib-humanize`
* :ref:`ref-contrib-redirects`
* :ref:`ref-contrib-sitemaps`
* :ref:`ref-contrib-sites`
* :ref:`ref-contrib-webdesign`
Solving specific problems
=========================
@ -120,11 +131,14 @@ Solving specific problems
And more:
---------
:ref:`Authenticating in Apache <howto-apache-auth>` ...
:ref:`howto-custom-file-storage` ... :ref:`howto-custom-management-commands` ...
:ref:`howto-custom-model-fields` ... :ref:`howto-error-reporting` ...
:ref:`howto-initial-data` ... :ref:`howto-static-files`
* :ref:`Authenticating in Apache <howto-apache-auth>`
* :ref:`howto-custom-file-storage`
* :ref:`howto-custom-management-commands`
* :ref:`howto-custom-model-fields`
* :ref:`howto-error-reporting`
* :ref:`howto-initial-data`
* :ref:`howto-static-files`
Reference
=========
@ -143,9 +157,13 @@ Reference
And more:
---------
:ref:`ref-databases` ... :ref:`ref-django-admin` ... :ref:`ref-files-index` ...
:ref:`ref-generic-views` ... :ref:`ref-middleware` ...
:ref:`ref-templates-index` ... :ref:`ref-unicode`
* :ref:`ref-databases`
* :ref:`ref-django-admin`
* :ref:`ref-files-index`
* :ref:`ref-generic-views`
* :ref:`ref-middleware`
* :ref:`ref-templates-index`
* :ref:`ref-unicode`
And all the rest
================

View file

@ -0,0 +1,212 @@
.. _ref-contrib-comments-index:
===========================
Django's comments framework
===========================
.. module:: django.contrib.comments
:synopsis: Django's comment framework
Django includes a simple, yet customizable comments framework. The built-in
comments framework can be used to attach comments to any model, so you can use
it for comments on blog entries, photos, book chapters, or anything else.
.. note::
If you used to use Django's older (undocumented) comments framework, you'll
need to upgrade. See the :ref:`upgrade guide <ref-contrib-comments-upgrade>`
for instructions.
Quick start guide
=================
To get started using the ``comments`` app, follow these steps:
#. Install the comments framework by adding ``'django.contrib.comments'`` to
:setting:`INSTALLED_APPS`.
#. Run ``manage.py syncdb`` so that Django will create the comment tables.
#. Add the comment app's URLs to your project's ``urls.py``:
.. code-block:: python
urlpatterns = patterns('',
...
(r'^comments/', include('django.contrib.comments.urls')),
...
)
#. Use the `comment template tags`_ below to embed comments in your
templates.
You might also want to examine the :ref:`ref-contrib-comments-settings`
Comment template tags
=====================
You'll primarily interact with the comment system through a series of template
tags that let you embed comments and generate forms for your users to post them.
Like all custom template tag libraries, you'll need to :ref:`load the custom
tags <loading-custom-template-libraries>` before you can use them::
{% load comments %}
Once loaded you can use the template tags below.
Specifying which object comments are attached to
------------------------------------------------
Django's comments are all "attached" to some parent object. This can be any
instance of a Django model. Each of the tags below gives you a couple of
different ways you can specify which object to attach to:
#. Refer to the object directly -- the more common method. Most of the
time, you'll have some object in the template's context you want
to attach the comment to; you can simply use that object.
For example, in a blog entry page that has a variable named ``entry``,
you could use the following to load the number of comments::
{% get_comment_count for entry as comment_count %}.
#. Refer to the object by content-type and object id. You'd use this method
if you, for some reason, don't actually have direct access to the object.
Following the above example, if you knew the object ID was ``14`` but
didn't have access to the actual object, you could do something like::
{% get_comment_count for blog.entry 14 as comment_count %}
In the above, ``blog.entry`` is the app label and (lower-cased) model
name of the model class.
.. templatetag:: get_comment_list
Displaying comments
-------------------
To get a the list of comments for some object, use :ttag:`get_comment_list`::
{% get_comment_list for [object] as [varname] %}
For example::
{% get_comment_list for event as comment_list %}
{% for comment in comment_list %}
...
{% endfor %}
.. templatetag:: get_comment_count
Counting comments
-----------------
To count comments attached to an object, use :ttag:`get_comment_count`::
{% get_comment_count for [object] as [varname] %}
For example::
{% get_comment_count for event as comment_count %}
<p>This event has {{ comment_count }} comments.</p>
Displaying the comment post form
--------------------------------
To show the form that users will use to post a comment, you can use
:ttag:`render_comment_form` or :ttag:`get_comment_form`
.. templatetag:: render_comment_form
Quickly rendering the comment form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The easiest way to display a comment form is by using
:ttag:`render_comment_form`::
{% render_comment_form for [object] %}
For example::
{% render_comment_form for event %}
This will render comments using a template named ``comments/form.html``, a
default version of which is included with Django.
.. templatetag:: get_comment_form
Rendering a custom comment form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you want more control over the look and feel of the comment form, you use use
:ttag:`get_comment_form` to get a :ref:`form object <topics-forms-index>` that
you can use in the template::
{% get_comment_form for [object] %}
A complete form might look like::
{% get_comment_form for event %}
<form action="{% comment_form_target %}" method="POST">
{{ form }}
<p class="submit">
<input type="submit" name="submit" class="submit-post" value="Preview">
</p>
</form>
Be sure to read the `notes on the comment form`_, below, for some special
considerations you'll need to make if you're using this aproach.
.. templatetag:: comment_form_target
Getting the comment form target
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You may have noticed that the above example uses another template tag --
:ttag:`comment_form_target` -- to actually get the ``action`` attribute of the
form. This will always return the correct URL that comments should be posted to;
you'll always want to use it like above::
<form action="{% comment_form_target %}" method="POST">
Notes on the comment form
-------------------------
The form used by the comment system has a few important anti-spam attributes you
should know about:
* It contains a number of hidden fields that contain timestamps, information
about the object the comment should be attached to, and a "security hash"
used to validate this information. If someone tampers with this data --
something comment spammers will try -- the comment submission will fail.
If you're rendering a custom comment form, you'll need to make sure to
pass these values through unchanged.
* The timestamp is used to ensure that "reply attacks" can't continue very
long. Users who wait too long between requesting the form and posting a
comment will have their submissions refused.
* The comment form includes a "honeypot_" field. It's a trap: if any data is
entered in that field, the comment will be considered spam (spammers often
automatically fill in all fields in an attempt to make valid submissions).
The default form hides this field with a piece of CSS and further labels
it with a warning field; if you use the comment form with a custom
template you should be sure to do the same.
.. _honeypot: http://en.wikipedia.org/wiki/Honeypot_(computing)
More information
================
.. toctree::
:maxdepth: 1
settings
upgrade

View file

@ -0,0 +1,34 @@
.. _ref-contrib-comments-settings:
================
Comment settings
================
These settings configure the behavior of the comments framework:
.. setting:: COMMENTS_HIDE_REMOVED
COMMENTS_HIDE_REMOVED
---------------------
If ``True`` (default), removed comments will be excluded from comment
lists/counts (as taken from template tags). Otherwise, the template author is
responsible for some sort of a "this comment has been removed by the site staff"
message.
.. setting:: COMMENT_MAX_LENGTH
COMMENT_MAX_LENGTH
------------------
The maximum length of the comment field, in characters. Comments longer than
this will be rejected. Defaults to 3000.
.. setting:: COMENTS_APP
COMENTS_APP
-----------
The app (i.e. entry in ``INSTALLED_APPS``) responsible for all "business logic."
You can change this to provide custom comment models and forms, though this is
currently undocumented.

View file

@ -0,0 +1,63 @@
.. _ref-contrib-comments-upgrade:
===============================================
Upgrading from Django's previous comment system
===============================================
Prior versions of Django included an outdated, undocumented comment system. Users who reverse-engineered this framework will need to upgrade to use the
new comment system; this guide explains how.
The main changes from the old system are:
* This new system is documented.
* It uses modern Django features like :ref:`forms <topics-forms-index>` and
:ref:`modelforms <topics-forms-modelforms>`.
* It has a single ``Comment`` model instead of separate ``FreeComment`` and
``Comment`` models.
* Comments have "email" and "URL" fields.
* No ratings, photos and karma. This should only effect World Online.
* The ``{% comment_form %}`` tag no longer exists. Instead, there's now two
functions: ``{% get_comment_form %}``, which returns a form for posting a
new comment, and ``{% render_comment_form %}``, which renders said form
using the ``comments/form.html`` template.
Upgrading data
--------------
The data models have changed, as have the table names. To transfer your data into the new system, you'll need to directly run the following SQL:
.. code-block:: sql
BEGIN;
INSERT INTO django_comments
(content_type_id, object_pk, site_id, user_name, user_email, user_url,
comment, submit_date, ip_address, is_public, is_removed)
SELECT
content_type_id, object_id, site_id, person_name, '', '', comment,
submit_date, ip_address, is_public, approved
FROM comments_freecomment;
INSERT INTO django_comments
(content_type_id, object_pk, site_id, user_id, comment, submit_date,
ip_address, is_public, is_removed)
SELECT
content_type_id, object_id, site_id, user_id, comment, submit_date,
ip_address, is_public, is_removed
FROM comments_comment;
UPDATE django_comments SET user_name = (
SELECT username FROM auth_user
WHERE django_comments.user_id = auth_user.id
);
UPDATE django_comments SET user_email = (
SELECT email FROM auth_user
WHERE django_comments.user_id = auth_user.id
);
COMMIT;

View file

@ -26,6 +26,7 @@ those packages have.
admin
auth
comments/index
contenttypes
csrf
databrowse
@ -58,7 +59,9 @@ See :ref:`topics-auth`.
comments
========
A simple yet flexible comments system. This is not yet documented.
**New in Django development version.**
A simple yet flexible comments system. See :ref:`ref-contrib-comments-index`.
contenttypes
============

View file

@ -607,6 +607,8 @@ along with all the fields available on that object.
Taken together, the documentation pages should tell you every tag, filter,
variable and object available to you in a given template.
.. _loading-custom-template-libraries:
Custom tag and filter libraries
===============================