2011-10-18 02:45:22 +08:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
from django import http
|
|
|
|
from django.conf import settings
|
2011-10-18 02:45:22 +08:00
|
|
|
from django.contrib import comments
|
|
|
|
from django.contrib.comments import signals
|
|
|
|
from django.contrib.comments.views.utils import next_redirect, confirmation_view
|
2010-03-17 06:37:45 +08:00
|
|
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
2008-08-26 06:14:22 +08:00
|
|
|
from django.db import models
|
2006-05-02 09:31:56 +08:00
|
|
|
from django.shortcuts import render_to_response
|
|
|
|
from django.template import RequestContext
|
2008-08-26 06:14:22 +08:00
|
|
|
from django.template.loader import render_to_string
|
|
|
|
from django.utils.html import escape
|
2009-10-27 08:36:34 +08:00
|
|
|
from django.views.decorators.csrf import csrf_protect
|
2011-10-18 02:45:22 +08:00
|
|
|
from django.views.decorators.http import require_POST
|
|
|
|
|
|
|
|
|
2008-07-19 07:54:34 +08:00
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
class CommentPostBadRequest(http.HttpResponseBadRequest):
|
2008-07-19 07:54:34 +08:00
|
|
|
"""
|
2008-08-26 06:14:22 +08:00
|
|
|
Response returned when a comment post is invalid. If ``DEBUG`` is on a
|
|
|
|
nice-ish error message will be displayed (for debugging purposes), but in
|
|
|
|
production mode a simple opaque 400 page will be displayed.
|
2008-07-19 07:54:34 +08:00
|
|
|
"""
|
2008-08-26 06:14:22 +08:00
|
|
|
def __init__(self, why):
|
|
|
|
super(CommentPostBadRequest, self).__init__()
|
|
|
|
if settings.DEBUG:
|
|
|
|
self.content = render_to_string("comments/400-debug.html", {"why": why})
|
2005-07-13 09:25:57 +08:00
|
|
|
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
@csrf_protect
|
|
|
|
@require_POST
|
2009-12-22 23:18:51 +08:00
|
|
|
def post_comment(request, next=None, using=None):
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
2008-08-26 06:14:22 +08:00
|
|
|
Post a comment.
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are
|
|
|
|
errors a preview template, ``comments/preview.html``, will be rendered.
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
2008-08-26 06:14:22 +08:00
|
|
|
# Fill out some initial data fields from an authenticated user, if present
|
|
|
|
data = request.POST.copy()
|
|
|
|
if request.user.is_authenticated():
|
2008-08-31 05:30:02 +08:00
|
|
|
if not data.get('name', ''):
|
2008-10-05 13:07:32 +08:00
|
|
|
data["name"] = request.user.get_full_name() or request.user.username
|
2008-08-31 05:30:02 +08:00
|
|
|
if not data.get('email', ''):
|
2008-08-26 06:14:22 +08:00
|
|
|
data["email"] = request.user.email
|
|
|
|
|
2009-06-17 21:01:40 +08:00
|
|
|
# Check to see if the POST data overrides the view's next argument.
|
|
|
|
next = data.get("next", next)
|
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
# Look up the object we're trying to comment about
|
|
|
|
ctype = data.get("content_type")
|
|
|
|
object_pk = data.get("object_pk")
|
|
|
|
if ctype is None or object_pk is None:
|
|
|
|
return CommentPostBadRequest("Missing content_type or object_pk field.")
|
2005-07-13 09:25:57 +08:00
|
|
|
try:
|
2008-08-26 06:14:22 +08:00
|
|
|
model = models.get_model(*ctype.split(".", 1))
|
2009-12-22 23:18:51 +08:00
|
|
|
target = model._default_manager.using(using).get(pk=object_pk)
|
2008-08-26 06:14:22 +08:00
|
|
|
except TypeError:
|
|
|
|
return CommentPostBadRequest(
|
|
|
|
"Invalid content_type value: %r" % escape(ctype))
|
|
|
|
except AttributeError:
|
|
|
|
return CommentPostBadRequest(
|
|
|
|
"The given content-type %r does not resolve to a valid model." % \
|
|
|
|
escape(ctype))
|
2005-07-13 09:25:57 +08:00
|
|
|
except ObjectDoesNotExist:
|
2008-08-26 06:14:22 +08:00
|
|
|
return CommentPostBadRequest(
|
|
|
|
"No object matching content-type %r and object PK %r exists." % \
|
|
|
|
(escape(ctype), escape(object_pk)))
|
2012-04-29 00:09:37 +08:00
|
|
|
except (ValueError, ValidationError) as e:
|
2010-03-17 06:37:45 +08:00
|
|
|
return CommentPostBadRequest(
|
|
|
|
"Attempting go get content-type %r and object PK %r exists raised %s" % \
|
|
|
|
(escape(ctype), escape(object_pk), e.__class__.__name__))
|
2008-08-26 06:14:22 +08:00
|
|
|
|
|
|
|
# Do we want to preview the comment?
|
2008-10-05 13:09:21 +08:00
|
|
|
preview = "preview" in data
|
2008-08-26 06:14:22 +08:00
|
|
|
|
|
|
|
# Construct the comment form
|
|
|
|
form = comments.get_form()(target, data=data)
|
|
|
|
|
|
|
|
# Check security information
|
|
|
|
if form.security_errors():
|
|
|
|
return CommentPostBadRequest(
|
|
|
|
"The comment form failed security verification: %s" % \
|
|
|
|
escape(str(form.security_errors())))
|
|
|
|
|
|
|
|
# If there are errors or if we requested a preview show the comment
|
|
|
|
if form.errors or preview:
|
|
|
|
template_list = [
|
2010-01-28 19:30:29 +08:00
|
|
|
# These first two exist for purely historical reasons.
|
|
|
|
# Django v1.0 and v1.1 allowed the underscore format for
|
|
|
|
# preview templates, so we have to preserve that format.
|
|
|
|
"comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.module_name),
|
2008-08-26 06:14:22 +08:00
|
|
|
"comments/%s_preview.html" % model._meta.app_label,
|
2011-08-12 22:14:15 +08:00
|
|
|
# Now the usual directory based template hierarchy.
|
2010-01-28 19:30:29 +08:00
|
|
|
"comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.module_name),
|
|
|
|
"comments/%s/preview.html" % model._meta.app_label,
|
2008-08-26 06:14:22 +08:00
|
|
|
"comments/preview.html",
|
|
|
|
]
|
|
|
|
return render_to_response(
|
|
|
|
template_list, {
|
|
|
|
"comment" : form.data.get("comment", ""),
|
|
|
|
"form" : form,
|
2009-04-08 03:28:13 +08:00
|
|
|
"next": next,
|
2008-10-05 13:09:21 +08:00
|
|
|
},
|
2008-08-26 06:14:22 +08:00
|
|
|
RequestContext(request, {})
|
|
|
|
)
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
# Otherwise create the comment
|
|
|
|
comment = form.get_comment_object()
|
|
|
|
comment.ip_address = request.META.get("REMOTE_ADDR", None)
|
|
|
|
if request.user.is_authenticated():
|
|
|
|
comment.user = request.user
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
# Signal that the comment is about to be saved
|
2008-08-27 02:53:52 +08:00
|
|
|
responses = signals.comment_will_be_posted.send(
|
|
|
|
sender = comment.__class__,
|
|
|
|
comment = comment,
|
|
|
|
request = request
|
|
|
|
)
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
for (receiver, response) in responses:
|
|
|
|
if response == False:
|
|
|
|
return CommentPostBadRequest(
|
|
|
|
"comment_will_be_posted receiver %r killed the comment" % receiver.__name__)
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2008-08-26 06:14:22 +08:00
|
|
|
# Save the comment and signal that it was saved
|
|
|
|
comment.save()
|
2008-08-27 02:53:52 +08:00
|
|
|
signals.comment_was_posted.send(
|
|
|
|
sender = comment.__class__,
|
|
|
|
comment = comment,
|
|
|
|
request = request
|
|
|
|
)
|
2008-08-26 06:14:22 +08:00
|
|
|
|
|
|
|
return next_redirect(data, next, comment_done, c=comment._get_pk_val())
|
|
|
|
|
|
|
|
comment_done = confirmation_view(
|
|
|
|
template = "comments/posted.html",
|
|
|
|
doc = """Display a "comment was posted" success page."""
|
|
|
|
)
|
2005-07-13 09:25:57 +08:00
|
|
|
|