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):
|
---|
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 | next = data.get("next")
|
---|
35 | if request.user.is_authenticated():
|
---|
36 | if not data.get('name', ''):
|
---|
37 | data["name"] = request.user.get_full_name() or request.user.username
|
---|
38 | if not data.get('email', ''):
|
---|
39 | data["email"] = request.user.email
|
---|
40 |
|
---|
41 | # Look up the object we're trying to comment about
|
---|
42 | ctype = data.get("content_type")
|
---|
43 | object_pk = data.get("object_pk")
|
---|
44 | if ctype is None or object_pk is None:
|
---|
45 | return CommentPostBadRequest("Missing content_type or object_pk field.")
|
---|
46 | try:
|
---|
47 | model = models.get_model(*ctype.split(".", 1))
|
---|
48 | target = model._default_manager.get(pk=object_pk)
|
---|
49 | except TypeError:
|
---|
50 | return CommentPostBadRequest(
|
---|
51 | "Invalid content_type value: %r" % escape(ctype))
|
---|
52 | except AttributeError:
|
---|
53 | return CommentPostBadRequest(
|
---|
54 | "The given content-type %r does not resolve to a valid model." % \
|
---|
55 | escape(ctype))
|
---|
56 | except ObjectDoesNotExist:
|
---|
57 | return CommentPostBadRequest(
|
---|
58 | "No object matching content-type %r and object PK %r exists." % \
|
---|
59 | (escape(ctype), escape(object_pk)))
|
---|
60 |
|
---|
61 | # Do we want to preview the comment?
|
---|
62 | preview = "preview" in data
|
---|
63 |
|
---|
64 | # Construct the comment form
|
---|
65 | form = comments.get_form()(target, data=data)
|
---|
66 |
|
---|
67 | # Check security information
|
---|
68 | if form.security_errors():
|
---|
69 | return CommentPostBadRequest(
|
---|
70 | "The comment form failed security verification: %s" % \
|
---|
71 | escape(str(form.security_errors())))
|
---|
72 |
|
---|
73 | # If there are errors or if we requested a preview show the comment
|
---|
74 | if form.errors or preview:
|
---|
75 | template_list = [
|
---|
76 | "comments/%s_%s_preview.html" % tuple(str(model._meta).split(".")),
|
---|
77 | "comments/%s_preview.html" % model._meta.app_label,
|
---|
78 | "comments/preview.html",
|
---|
79 | ]
|
---|
80 | return render_to_response(
|
---|
81 | template_list, {
|
---|
82 | "comment" : form.data.get("comment", ""),
|
---|
83 | "form" : form,
|
---|
84 | "next": next,
|
---|
85 | },
|
---|
86 | RequestContext(request, {})
|
---|
87 | )
|
---|
88 |
|
---|
89 | # Otherwise create the comment
|
---|
90 | comment = form.get_comment_object()
|
---|
91 | comment.ip_address = request.META.get("REMOTE_ADDR", None)
|
---|
92 | if request.user.is_authenticated():
|
---|
93 | comment.user = request.user
|
---|
94 |
|
---|
95 | # Signal that the comment is about to be saved
|
---|
96 | responses = signals.comment_will_be_posted.send(
|
---|
97 | sender = comment.__class__,
|
---|
98 | comment = comment,
|
---|
99 | request = request
|
---|
100 | )
|
---|
101 |
|
---|
102 | for (receiver, response) in responses:
|
---|
103 | if response == False:
|
---|
104 | return CommentPostBadRequest(
|
---|
105 | "comment_will_be_posted receiver %r killed the comment" % receiver.__name__)
|
---|
106 |
|
---|
107 | # Save the comment and signal that it was saved
|
---|
108 | comment.save()
|
---|
109 | signals.comment_was_posted.send(
|
---|
110 | sender = comment.__class__,
|
---|
111 | comment = comment,
|
---|
112 | request = request
|
---|
113 | )
|
---|
114 |
|
---|
115 | return next_redirect(data, next, comment_done, c=comment._get_pk_val())
|
---|
116 |
|
---|
117 | post_comment = require_POST(post_comment)
|
---|
118 |
|
---|
119 | comment_done = confirmation_view(
|
---|
120 | template = "comments/posted.html",
|
---|
121 | doc = """Display a "comment was posted" success page."""
|
---|
122 | )
|
---|
123 |
|
---|