web/lib/django/contrib/comments/views/comments.py
changeset 0 0d40e90630ef
child 29 cc9b7e14412b
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     1 from django import http
       
     2 from django.conf import settings
       
     3 from utils import next_redirect, confirmation_view
       
     4 from django.core.exceptions import ObjectDoesNotExist
       
     5 from django.db import models
       
     6 from django.shortcuts import render_to_response
       
     7 from django.template import RequestContext
       
     8 from django.template.loader import render_to_string
       
     9 from django.utils.html import escape
       
    10 from django.views.decorators.http import require_POST
       
    11 from django.contrib import comments
       
    12 from django.contrib.comments import signals
       
    13 
       
    14 class CommentPostBadRequest(http.HttpResponseBadRequest):
       
    15     """
       
    16     Response returned when a comment post is invalid. If ``DEBUG`` is on a
       
    17     nice-ish error message will be displayed (for debugging purposes), but in
       
    18     production mode a simple opaque 400 page will be displayed.
       
    19     """
       
    20     def __init__(self, why):
       
    21         super(CommentPostBadRequest, self).__init__()
       
    22         if settings.DEBUG:
       
    23             self.content = render_to_string("comments/400-debug.html", {"why": why})
       
    24 
       
    25 def post_comment(request, next=None):
       
    26     """
       
    27     Post a comment.
       
    28 
       
    29     HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are
       
    30     errors a preview template, ``comments/preview.html``, will be rendered.
       
    31     """
       
    32     # Fill out some initial data fields from an authenticated user, if present
       
    33     data = request.POST.copy()
       
    34     if request.user.is_authenticated():
       
    35         if not data.get('name', ''):
       
    36             data["name"] = request.user.get_full_name() or request.user.username
       
    37         if not data.get('email', ''):
       
    38             data["email"] = request.user.email
       
    39 
       
    40     # Check to see if the POST data overrides the view's next argument.
       
    41     next = data.get("next", next)
       
    42 
       
    43     # Look up the object we're trying to comment about
       
    44     ctype = data.get("content_type")
       
    45     object_pk = data.get("object_pk")
       
    46     if ctype is None or object_pk is None:
       
    47         return CommentPostBadRequest("Missing content_type or object_pk field.")
       
    48     try:
       
    49         model = models.get_model(*ctype.split(".", 1))
       
    50         target = model._default_manager.get(pk=object_pk)
       
    51     except TypeError:
       
    52         return CommentPostBadRequest(
       
    53             "Invalid content_type value: %r" % escape(ctype))
       
    54     except AttributeError:
       
    55         return CommentPostBadRequest(
       
    56             "The given content-type %r does not resolve to a valid model." % \
       
    57                 escape(ctype))
       
    58     except ObjectDoesNotExist:
       
    59         return CommentPostBadRequest(
       
    60             "No object matching content-type %r and object PK %r exists." % \
       
    61                 (escape(ctype), escape(object_pk)))
       
    62 
       
    63     # Do we want to preview the comment?
       
    64     preview = "preview" in data
       
    65 
       
    66     # Construct the comment form
       
    67     form = comments.get_form()(target, data=data)
       
    68 
       
    69     # Check security information
       
    70     if form.security_errors():
       
    71         return CommentPostBadRequest(
       
    72             "The comment form failed security verification: %s" % \
       
    73                 escape(str(form.security_errors())))
       
    74 
       
    75     # If there are errors or if we requested a preview show the comment
       
    76     if form.errors or preview:
       
    77         template_list = [
       
    78             "comments/%s_%s_preview.html" % tuple(str(model._meta).split(".")),
       
    79             "comments/%s_preview.html" % model._meta.app_label,
       
    80             "comments/preview.html",
       
    81         ]
       
    82         return render_to_response(
       
    83             template_list, {
       
    84                 "comment" : form.data.get("comment", ""),
       
    85                 "form" : form,
       
    86                 "next": next,
       
    87             },
       
    88             RequestContext(request, {})
       
    89         )
       
    90 
       
    91     # Otherwise create the comment
       
    92     comment = form.get_comment_object()
       
    93     comment.ip_address = request.META.get("REMOTE_ADDR", None)
       
    94     if request.user.is_authenticated():
       
    95         comment.user = request.user
       
    96 
       
    97     # Signal that the comment is about to be saved
       
    98     responses = signals.comment_will_be_posted.send(
       
    99         sender  = comment.__class__,
       
   100         comment = comment,
       
   101         request = request
       
   102     )
       
   103 
       
   104     for (receiver, response) in responses:
       
   105         if response == False:
       
   106             return CommentPostBadRequest(
       
   107                 "comment_will_be_posted receiver %r killed the comment" % receiver.__name__)
       
   108 
       
   109     # Save the comment and signal that it was saved
       
   110     comment.save()
       
   111     signals.comment_was_posted.send(
       
   112         sender  = comment.__class__,
       
   113         comment = comment,
       
   114         request = request
       
   115     )
       
   116 
       
   117     return next_redirect(data, next, comment_done, c=comment._get_pk_val())
       
   118 
       
   119 post_comment = require_POST(post_comment)
       
   120 
       
   121 comment_done = confirmation_view(
       
   122     template = "comments/posted.html",
       
   123     doc = """Display a "comment was posted" success page."""
       
   124 )
       
   125