180 lines
6.5 KiB
Plaintext
180 lines
6.5 KiB
Plaintext
|
.. _ref-contrib-comments-custom:
|
||
|
|
||
|
==================================
|
||
|
Customizing the comments framework
|
||
|
==================================
|
||
|
|
||
|
.. currentmodule:: django.contrib.comments
|
||
|
|
||
|
If the built-in comment framework doesn't quite fit your needs, you can extend
|
||
|
the comment app's behavior to add custom data and logic. The comments framework
|
||
|
lets you extend the built-in comment model, the built-in comment form, and the
|
||
|
various comment views.
|
||
|
|
||
|
The :setting:`COMMENTS_APP` setting is where this customization begins. Set
|
||
|
:setting:`COMMENTS_APP` to the name of the app you'd like to use to provide
|
||
|
custom behavior. You'll use the same syntax as you'd use for
|
||
|
:setting:`INSTALLED_APPS`, and the app given must also be in the
|
||
|
:setting:`INSTALLED_APPS` list.
|
||
|
|
||
|
For example, if you wanted to use an app named ``my_comment_app``, your
|
||
|
settings file would contain::
|
||
|
|
||
|
INSTALLED_APPS = [
|
||
|
...
|
||
|
'my_comment_app',
|
||
|
...
|
||
|
]
|
||
|
|
||
|
COMMENTS_APP = 'my_comment_app'
|
||
|
|
||
|
The app named in :setting:`COMMENTS_APP` provides its custom behavior by
|
||
|
defining some module-level functions in the app's ``__init__.py``. The
|
||
|
:ref:`complete list of these functions <custom-comment-app-api>` can be found
|
||
|
below, but first let's look at a quick example.
|
||
|
|
||
|
An example custom comments app
|
||
|
==============================
|
||
|
|
||
|
One of the most common types of customization is modifying the set of fields
|
||
|
provided on the built-in comment model. For example, some sites that allow
|
||
|
comments want the commentator to provide a title for their comment; the built-in
|
||
|
comment model has no field for that title.
|
||
|
|
||
|
To make this kind of customization, we'll need to do three things:
|
||
|
|
||
|
#. Create a custom comment :class:`~django.db.models.Model` that adds on the
|
||
|
"title" field.
|
||
|
|
||
|
#. Create a custom comment :class:`~django.forms.Form` that also adds this
|
||
|
"title" field.
|
||
|
|
||
|
#. Inform Django of these objects by defining a few functions in a
|
||
|
custom :setting:`COMMENTS_APP`.
|
||
|
|
||
|
So, carrying on the example above, we're dealing with a typical app structure in
|
||
|
the ``my_custom_app`` directory::
|
||
|
|
||
|
my_custom_app/
|
||
|
__init__.py
|
||
|
models.py
|
||
|
forms.py
|
||
|
|
||
|
In the ``models.py`` we'll define a ``CommentWithTitle`` model::
|
||
|
|
||
|
from django.db import models
|
||
|
from django.contrib.comments.models import BaseCommentAbstractModel
|
||
|
|
||
|
class CommentWithTitle(BaseCommentAbstractModel):
|
||
|
title = models.CharField(max_length=300)
|
||
|
|
||
|
All custom comment models must subclass :class:`BaseCommentAbstractModel`.
|
||
|
|
||
|
Next, we'll define a custom comment form in ``forms.py``. This is a little more
|
||
|
tricky: we have to both create a form and override
|
||
|
:meth:`CommentForm.get_comment_model` and
|
||
|
:meth:`CommentForm.get_comment_create_data` to return deal with our custom title
|
||
|
field::
|
||
|
|
||
|
from django import forms
|
||
|
from django.contrib.comments.forms import CommentForm
|
||
|
from my_comment_app.models import CommentWithTitle
|
||
|
|
||
|
class CommentFormWithTitle(CommentForm):
|
||
|
title = forms.CharField(max_length=300)
|
||
|
|
||
|
def get_comment_model(self):
|
||
|
# Use our custom comment model instead of the built-in one.
|
||
|
return CommentWithTitle
|
||
|
|
||
|
def get_comment_create_data(self):
|
||
|
# Use the data of the superclass, and add in the title field
|
||
|
data = super(CommentFormWithTitle, self).get_comment_create_data()
|
||
|
data['title'] = self.cleaned_data['title']
|
||
|
return data
|
||
|
|
||
|
Finally, we'll define a couple of methods in ``my_custom_app/__init__.py`` to point Django at these classes we've created::
|
||
|
|
||
|
from my_comments_app.models import CommentWithTitle
|
||
|
from my_comments_app.forms import CommentFormWithTitle
|
||
|
|
||
|
def get_model():
|
||
|
return CommentWithTitle
|
||
|
|
||
|
def get_form():
|
||
|
return CommentFormWithTitle
|
||
|
|
||
|
The above process should take care of most common situations. For more advanced usage, there are additional methods you can define. Those are explained in the next section.
|
||
|
|
||
|
.. _custom-comment-app-api:
|
||
|
|
||
|
Custom comment app API
|
||
|
======================
|
||
|
|
||
|
The :mod:`django.contrib.comments` app defines the following methods; any custom comment app must define at least one of them. All are optional, however.
|
||
|
|
||
|
.. function:: get_model()
|
||
|
|
||
|
Return the :class:`~django.db.models.Model` class to use for comments. This
|
||
|
model should inherit from
|
||
|
:class:`django.contrib.comments.models.BaseCommentAbstractModel`, which
|
||
|
defines necessary core fields.
|
||
|
|
||
|
The default implementation returns
|
||
|
:class:`django.contrib.comments.models.Comment`.
|
||
|
|
||
|
.. function:: get_form()
|
||
|
|
||
|
Return the :class:`~django.forms.Form` class you want to use for
|
||
|
creating, validating, and saving your comment model. Your custom
|
||
|
comment form should accept an additional first argument,
|
||
|
``target_object``, which is the object the comment will be
|
||
|
attached to.
|
||
|
|
||
|
The default implementation returns
|
||
|
:class:`django.contrib.comments.forms.CommentForm`.
|
||
|
|
||
|
.. note::
|
||
|
|
||
|
The default comment form also includes a number of unobtrusive
|
||
|
spam-prevention features (see
|
||
|
:ref:`notes-on-the-comment-form`). If replacing it with your
|
||
|
own form, you may want to look at the source code for the
|
||
|
built-in form and consider incorporating similar features.
|
||
|
|
||
|
.. function:: get_form_target()
|
||
|
|
||
|
Return the URL for POSTing comments. This will be the ``<form action>``
|
||
|
attribute when rendering your comment form.
|
||
|
|
||
|
The default implementation returns a reverse-resolved URL pointing
|
||
|
to the :func:`post_comment` view.
|
||
|
|
||
|
.. note::
|
||
|
|
||
|
If you provide a custom comment model and/or form, but you
|
||
|
want to use the default :func:`post_comment` view, you will
|
||
|
need to be aware that it requires the model and form to have
|
||
|
certain additional attributes and methods: see the
|
||
|
:func:`post_comment` view documentation for details.
|
||
|
|
||
|
.. function:: get_flag_url()
|
||
|
|
||
|
Return the URL for the "flag this comment" view.
|
||
|
|
||
|
The default implementation returns a reverse-resolved URL pointing
|
||
|
to the :func:`django.contrib.comments.views.moderation.flag` view.
|
||
|
|
||
|
.. function:: get_delete_url()
|
||
|
|
||
|
Return the URL for the "delete this comment" view.
|
||
|
|
||
|
The default implementation returns a reverse-resolved URL pointing
|
||
|
to the :func:`django.contrib.comments.views.moderation.delete` view.
|
||
|
|
||
|
.. function:: get_approve_url()
|
||
|
|
||
|
Return the URL for the "approve this comment from moderation" view.
|
||
|
|
||
|
The default implementation returns a reverse-resolved URL pointing
|
||
|
to the :func:`django.contrib.comments.views.moderation.approve` view.
|