Ticket #9268: comments.py

File comments.py, 4.5 KB (added by stuartk, 15 years ago)

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

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