1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
==================================
Customizing the comments framework
==================================
.. currentmodule:: django_comments
If the 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 in comment model, the 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 comment model. For example, some sites that allow
comments want the commentator to provide a title for their comment; the
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_comment_app`` directory::
my_comment_app/
__init__.py
models.py
forms.py
In the ``models.py`` we'll define a ``CommentWithTitle`` model::
from django.db import models
from django_comments.abstracts import CommentAbstractModel
class CommentWithTitle(CommentAbstractModel):
title = models.CharField(max_length=300)
Most custom comment models will subclass the
:class:`~django_comments.abstracts.CommentAbstractModel` model. However,
if you want to substantially remove or change the fields available in the
:class:`~django_comments.abstracts.CommentAbstractModel` model, but don't want
to rewrite the templates, you could try subclassing from
``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
``CommentForm.get_comment_create_data()`` to return deal with our custom title
field::
from django import forms
from django_comments.forms import CommentForm
from my_comment_app.models import CommentWithTitle
class CommentFormWithTitle(CommentForm):
title = forms.CharField(max_length=300)
def get_comment_create_data(self, **kwargs):
# Use the data of the superclass, and add in the title field
data = super().get_comment_create_data(**kwargs)
data['title'] = self.cleaned_data['title']
return data
Django provides a couple of "helper" classes to make writing certain types of
custom comment forms easier; see :mod:`django_comments.forms` for
more.
Finally, we'll define a couple of methods in ``my_comment_app/__init__.py`` to
point Django at these classes we've created::
def get_model():
from my_comment_app.models import CommentWithTitle
return CommentWithTitle
def get_form():
from my_comment_app.forms import CommentFormWithTitle
return CommentFormWithTitle
The class imports have to be inside functions, as recent Django versions do not
allow importing models in the application root ``__init__.py`` file.
.. warning::
Be careful not to create cyclic imports in your custom comments app.
If you feel your comment configuration isn't being used as defined --
for example, if your comment moderation policy isn't being applied --
you may have a cyclic import problem.
If you are having unexplained problems with comments behavior, check
if your custom comments application imports (even indirectly)
any module that itself imports Django's comments module.
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_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
``django_comments.abstracts.BaseCommentAbstractModel``, which
defines necessary core fields.
The default implementation returns
:class:`django_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_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
default 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 ``post_comment()`` view.
.. note::
If you provide a custom comment model and/or form, but you
want to use the default ``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
``django_comments.views.post_comment()`` view 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 ``django_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 ``django_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 ``django_comments.views.moderation.approve()`` view.
|