PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/django/contrib/comments/views/comments.py

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