1 from django import http |
1 from django import http |
2 from django.conf import settings |
2 from django.conf import settings |
3 from utils import next_redirect, confirmation_view |
3 from utils import next_redirect, confirmation_view |
4 from django.core.exceptions import ObjectDoesNotExist |
4 from django.core.exceptions import ObjectDoesNotExist, ValidationError |
5 from django.db import models |
5 from django.db import models |
6 from django.shortcuts import render_to_response |
6 from django.shortcuts import render_to_response |
7 from django.template import RequestContext |
7 from django.template import RequestContext |
8 from django.template.loader import render_to_string |
8 from django.template.loader import render_to_string |
9 from django.utils.html import escape |
9 from django.utils.html import escape |
10 from django.views.decorators.http import require_POST |
10 from django.views.decorators.http import require_POST |
11 from django.contrib import comments |
11 from django.contrib import comments |
12 from django.contrib.comments import signals |
12 from django.contrib.comments import signals |
|
13 from django.views.decorators.csrf import csrf_protect |
13 |
14 |
14 class CommentPostBadRequest(http.HttpResponseBadRequest): |
15 class CommentPostBadRequest(http.HttpResponseBadRequest): |
15 """ |
16 """ |
16 Response returned when a comment post is invalid. If ``DEBUG`` is on a |
17 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 nice-ish error message will be displayed (for debugging purposes), but in |
20 def __init__(self, why): |
21 def __init__(self, why): |
21 super(CommentPostBadRequest, self).__init__() |
22 super(CommentPostBadRequest, self).__init__() |
22 if settings.DEBUG: |
23 if settings.DEBUG: |
23 self.content = render_to_string("comments/400-debug.html", {"why": why}) |
24 self.content = render_to_string("comments/400-debug.html", {"why": why}) |
24 |
25 |
25 def post_comment(request, next=None): |
26 @csrf_protect |
|
27 @require_POST |
|
28 def post_comment(request, next=None, using=None): |
26 """ |
29 """ |
27 Post a comment. |
30 Post a comment. |
28 |
31 |
29 HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are |
32 HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are |
30 errors a preview template, ``comments/preview.html``, will be rendered. |
33 errors a preview template, ``comments/preview.html``, will be rendered. |
45 object_pk = data.get("object_pk") |
48 object_pk = data.get("object_pk") |
46 if ctype is None or object_pk is None: |
49 if ctype is None or object_pk is None: |
47 return CommentPostBadRequest("Missing content_type or object_pk field.") |
50 return CommentPostBadRequest("Missing content_type or object_pk field.") |
48 try: |
51 try: |
49 model = models.get_model(*ctype.split(".", 1)) |
52 model = models.get_model(*ctype.split(".", 1)) |
50 target = model._default_manager.get(pk=object_pk) |
53 target = model._default_manager.using(using).get(pk=object_pk) |
51 except TypeError: |
54 except TypeError: |
52 return CommentPostBadRequest( |
55 return CommentPostBadRequest( |
53 "Invalid content_type value: %r" % escape(ctype)) |
56 "Invalid content_type value: %r" % escape(ctype)) |
54 except AttributeError: |
57 except AttributeError: |
55 return CommentPostBadRequest( |
58 return CommentPostBadRequest( |
57 escape(ctype)) |
60 escape(ctype)) |
58 except ObjectDoesNotExist: |
61 except ObjectDoesNotExist: |
59 return CommentPostBadRequest( |
62 return CommentPostBadRequest( |
60 "No object matching content-type %r and object PK %r exists." % \ |
63 "No object matching content-type %r and object PK %r exists." % \ |
61 (escape(ctype), escape(object_pk))) |
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__)) |
62 |
69 |
63 # Do we want to preview the comment? |
70 # Do we want to preview the comment? |
64 preview = "preview" in data |
71 preview = "preview" in data |
65 |
72 |
66 # Construct the comment form |
73 # Construct the comment form |
73 escape(str(form.security_errors()))) |
80 escape(str(form.security_errors()))) |
74 |
81 |
75 # If there are errors or if we requested a preview show the comment |
82 # If there are errors or if we requested a preview show the comment |
76 if form.errors or preview: |
83 if form.errors or preview: |
77 template_list = [ |
84 template_list = [ |
78 "comments/%s_%s_preview.html" % tuple(str(model._meta).split(".")), |
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), |
79 "comments/%s_preview.html" % model._meta.app_label, |
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, |
80 "comments/preview.html", |
93 "comments/preview.html", |
81 ] |
94 ] |
82 return render_to_response( |
95 return render_to_response( |
83 template_list, { |
96 template_list, { |
84 "comment" : form.data.get("comment", ""), |
97 "comment" : form.data.get("comment", ""), |
114 request = request |
127 request = request |
115 ) |
128 ) |
116 |
129 |
117 return next_redirect(data, next, comment_done, c=comment._get_pk_val()) |
130 return next_redirect(data, next, comment_done, c=comment._get_pk_val()) |
118 |
131 |
119 post_comment = require_POST(post_comment) |
|
120 |
|
121 comment_done = confirmation_view( |
132 comment_done = confirmation_view( |
122 template = "comments/posted.html", |
133 template = "comments/posted.html", |
123 doc = """Display a "comment was posted" success page.""" |
134 doc = """Display a "comment was posted" success page.""" |
124 ) |
135 ) |
125 |
136 |