Ticket #8630: 8630_r9084.2.diff

File 8630_r9084.2.diff, 12.2 KB (added by Carl Meyer, 11 years ago)

consolidated patch, with docs

  • django/contrib/comments/admin.py

     
    22from django.conf import settings
    33from django.contrib.comments.models import Comment
    44from django.utils.translation import ugettext_lazy as _
     5from django.contrib.comments import get_model
    56
    67class CommentsAdmin(admin.ModelAdmin):
    78    fieldsets = (
     
    2223    ordering = ('-submit_date',)
    2324    search_fields = ('comment', 'user__username', 'user_name', 'user_email', 'user_url', 'ip_address')
    2425
    25 admin.site.register(Comment, CommentsAdmin)
     26if get_model() is Comment:
     27    admin.site.register(Comment, CommentsAdmin)
  • django/contrib/comments/__init__.py

     
    22from django.core import urlresolvers
    33from django.core.exceptions import ImproperlyConfigured
    44
    5 # Attributes required in the top-level app for COMMENTS_APP
    6 REQUIRED_COMMENTS_APP_ATTRIBUTES = ["get_model", "get_form", "get_form_target"]
    7 
    85def get_comment_app():
    96    """
    107    Get the comment app (i.e. "django.contrib.comments") as defined in the settings
     
    2219        raise ImproperlyConfigured("The COMMENTS_APP setting refers to "\
    2320                                   "a non-existing package.")
    2421
    25     # Make sure some specific attributes exist inside that package.
    26     for attribute in REQUIRED_COMMENTS_APP_ATTRIBUTES:
    27         if not hasattr(package, attribute):
    28             raise ImproperlyConfigured("The COMMENTS_APP package %r does not "\
    29                                        "define the (required) %r function" % \
    30                                             (package, attribute))
    31 
    3222    return package
    3323
    3424def get_comment_app_name():
     
    3929    return getattr(settings, 'COMMENTS_APP', 'django.contrib.comments')
    4030
    4131def get_model():
     32    if get_comment_app_name() != __name__ and hasattr(get_comment_app(), "get_model"):
     33        return get_comment_app().get_model()
    4234    from django.contrib.comments.models import Comment
    4335    return Comment
    4436
    4537def get_form():
     38    if get_comment_app_name() != __name__ and hasattr(get_comment_app(), "get_form"):
     39        return get_comment_app().get_form()
    4640    from django.contrib.comments.forms import CommentForm
    4741    return CommentForm
    4842
    4943def get_form_target():
     44    if get_comment_app_name() != __name__ and hasattr(get_comment_app(), "get_form_target"):
     45        return get_comment_app().get_form_target()
    5046    return urlresolvers.reverse("django.contrib.comments.views.comments.post_comment")
    5147
    5248def get_flag_url(comment):
     
    5551    """
    5652    if get_comment_app_name() != __name__ and hasattr(get_comment_app(), "get_flag_url"):
    5753        return get_comment_app().get_flag_url(comment)
    58     else:
    59         return urlresolvers.reverse("django.contrib.comments.views.moderation.flag", args=(comment.id,))
     54    return urlresolvers.reverse("django.contrib.comments.views.moderation.flag", args=(comment.id,))
    6055
    6156def get_delete_url(comment):
    6257    """
    6358    Get the URL for the "delete this comment" view.
    6459    """
    6560    if get_comment_app_name() != __name__ and hasattr(get_comment_app(), "get_delete_url"):
    66         return get_comment_app().get_flag_url(get_delete_url)
    67     else:
    68         return urlresolvers.reverse("django.contrib.comments.views.moderation.delete", args=(comment.id,))
     61        return get_comment_app().get_delete_url(comment)
     62    return urlresolvers.reverse("django.contrib.comments.views.moderation.delete", args=(comment.id,))
    6963
    7064def get_approve_url(comment):
    7165    """
     
    7367    """
    7468    if get_comment_app_name() != __name__ and hasattr(get_comment_app(), "get_approve_url"):
    7569        return get_comment_app().get_approve_url(comment)
    76     else:
    77         return urlresolvers.reverse("django.contrib.comments.views.moderation.approve", args=(comment.id,))
     70    return urlresolvers.reverse("django.contrib.comments.views.moderation.approve", args=(comment.id,))
  • docs/ref/contrib/comments/index.txt

     
    175175
    176176    <form action="{% comment_form_target %}" method="POST">
    177177
     178.. _notes-on-the-comment-form:
     179
    178180Notes on the comment form
    179181-------------------------
    180182
     
    212214   settings
    213215   signals
    214216   upgrade
    215 
     217   custom
  • docs/ref/contrib/comments/custom.txt

     
     1.. _ref-contrib-comments-custom:
     2
     3==================================
     4Customizing the comments framework
     5==================================
     6
     7Via the :setting:`COMMENTS_APP` setting, the comments framework allows
     8you to replace the built-in comment model and comment form with your
     9own classes.
     10
     11The COMMENTS_APP
     12================
     13
     14A custom :setting:`COMMENTS_APP` should define one or more of the
     15following module-level functions in it's ``__init__.py`` file. None of
     16these functions are required, so you can define any combination of
     17them (all others will use the defaults from
     18``django.contrib.comments``):
     19
     20.. function:: get_model()
     21
     22    Return the :class:`~django.db.models.Model` class to use for
     23    comments.  This model should inherit from
     24    :class:`django.contrib.comments.models.BaseCommentAbstractModel`,
     25    which defines necessary core fields.
     26
     27    The default implementation returns
     28    :class:`django.contrib.comments.models.Comment`.
     29
     30.. function:: get_form()
     31
     32    Return the :class:`~django.forms.Form` class you want to use for
     33    creating, validating, and saving your comment model.  Your custom
     34    comment form should accept an additional first argument,
     35    ``target_object``, which is the object the comment will be
     36    attached to.
     37
     38    The default implementation returns
     39    :class:`django.contrib.comments.forms.CommentForm`.
     40
     41    .. note::
     42       
     43        The default comment form also includes a number of unobtrusive
     44        spam-prevention features (see
     45        :ref:`notes-on-the-comment-form`).  If replacing it with your
     46        own form, you may want to look at the source code for the
     47        built-in form and consider incorporating similar features.
     48
     49.. function:: get_form_target()
     50
     51    Return the URL for POSTing comments.  This will be the ``action``
     52    attribute when rendering your comment form.
     53
     54    The default implementation returns a reverse-resolved URL pointing
     55    to the :func:`post_comment` view.
     56
     57    .. note::
     58
     59        If you provide a custom comment model and/or form, but you
     60        want to use the default :func:`post_comment` view, you will
     61        need to be aware that it requires the model and form to have
     62        certain additional attributes and methods: see the
     63        :func:`post_comment` view documentation for details.
     64
     65.. function:: get_flag_url()
     66
     67    Return the URL for the "flag this comment" view.
     68
     69    The default implementation returns a reverse-resolved URL pointing
     70    to the :func:`django.contrib.comments.views.moderation.flag` view.
     71
     72.. function:: get_delete_url()
     73
     74    Return the URL for the "delete this comment" view.
     75
     76    The default implementation returns a reverse-resolved URL pointing
     77    to the :func:`django.contrib.comments.views.moderation.delete` view.
     78
     79.. function:: get_approve_url()
     80
     81    Return the URL for the "approve this comment from moderation" view.
     82
     83    The default implementation returns a reverse-resolved URL pointing
     84    to the :func:`django.contrib.comments.views.moderation.approve` view.
     85
     86A sample custom comments app
     87----------------------------
     88
     89A custom comments app might have an ``__init__.py`` like this::
     90
     91    from django.core.urlresolvers import reverse
     92
     93    def get_model():
     94        from my_comments_app.models import MyComment
     95        return MyComment
     96
     97    def get_form():
     98        from my_comments_app.forms import MyCommentForm
     99        return MyCommentForm
     100
     101    def get_form_target():
     102        return reverse('my_comments_app.views.post_comment')
     103
     104
     105``MyComment`` should inherit from :class:`BaseCommentAbstractModel`,
     106so in ``models.py``::
     107
     108    from django.db import models
     109    from django.contrib.comments.models import BaseCommentAbstractModel
     110   
     111    class MyComment(BaseCommentAbstractModel):
     112        ... fields and custom methods ...
     113
     114And ``MyCommentForm`` should accept a target_object argument,
     115so in ``forms.py``::
     116
     117    from django import forms
     118
     119    class MyCommentForm(forms.Form):
     120        def __init__(self, target_object, data=None, initial=None):
     121            ...
     122
     123In order to enable this custom comments app, you would need to have
     124the following in your project's ``settings.py``::
     125
     126    INSTALLED_APPS = (
     127    ...
     128    'my_comments_app',
     129    ...
     130    )
     131
     132    COMMENTS_APP = 'my_comments_app'
     133
     134
     135API reference
     136==================================
     137
     138BaseCommentAbstractModel
     139------------------------
     140
     141.. class:: BaseCommentAbstractModel
     142
     143    :class:`BaseCommentAbstractModel` defines the following attributes
     144    and methods, which your custom comment model will inherit:
     145
     146    .. attribute:: site
     147
     148        A foreign key to the
     149        :class:`~django.contrib.sites.models.Site` model (see
     150        :ref:`ref-contrib-sites`), defining which site this comment
     151        appears on.
     152
     153    .. attribute:: content_type
     154
     155        A foreign key to the
     156        :class:`~django.contrib.contenttypes.models.ContentType`
     157        model.  This is the content type of the target object the
     158        comment is attached to.
     159
     160    .. attribute:: object_pk
     161
     162        The primary key of the target object.
     163
     164    .. attribute:: content_object
     165
     166        A
     167        :class:`~django.contrib.contenttypes.generic.GenericForeignKey`
     168        to the target object, using the :attr:`content_type` and
     169        :attr:`object_pk` attributes.
     170
     171    .. method:: get_content_object_url()
     172
     173        Returns a URL that redirects to the URL of the comment's
     174        target object.
     175
     176post_comment view
     177-----------------
     178
     179.. function:: post_comment
     180
     181    The default :func:`post_comment` view requires the comment model
     182    to have two additional fields:
     183
     184    .. attribute:: user
     185
     186        This should be a :class:`ForeignKey` to the :class:`User`
     187        model.  The view will store the user who posted the comment in
     188        this field.
     189
     190    .. attribute:: ip_address
     191
     192        This should be an :class:`IPAddressField`.  The
     193        :func:`post_comment` view will store the remote IP address of
     194        the comment poster in it.
     195
     196    The :func:`post_comment` view also requires the comment form to
     197    have the following two methods:
     198
     199    .. method:: security_errors()
     200
     201        If this method returns a false value, the form will be
     202        considered to have passed anti-spam screening.  If it returns
     203        any nonzero value, that value will be coerced to a string and
     204        sent as part of an HTTP 400 (bad request) response.
     205
     206    .. method:: get_comment_object()
     207
     208        This method will only be called if the form has passed
     209        validation and returned no :func:`security_errors()`.  It
     210        should return an (unsaved) comment object, which will be
     211        annotated with the user and IP address and then saved.
  • docs/ref/contrib/comments/settings.txt

     
    2929COMMENTS_APP
    3030------------
    3131
    32 The app (i.e. entry in ``INSTALLED_APPS``) responsible for all "business logic."
    33 You can change this to provide custom comment models and forms, though this is
    34 currently undocumented.
     32An app which provides :ref:`customization of the comments framework
     33<ref-contrib-comments-custom>`.  Use the same dotted-string notation
     34as in :setting:`INSTALLED_APPS`.  Your custom :setting:`COMMENTS_APP`
     35must also be listed in :setting:`INSTALLED_APPS`.
Back to Top