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

https://code.google.com/p/mango-py/ · Python · 136 lines · 102 code · 14 blank · 20 comment · 14 complexity · a832bc53a061c08897d46a94fc8f2d2f MD5 · raw file

  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, ValidationError
  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. from django.views.decorators.csrf import csrf_protect
  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. @csrf_protect
  25. @require_POST
  26. def post_comment(request, next=None, using=None):
  27. """
  28. Post a comment.
  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. # Check to see if the POST data overrides the view's next argument.
  40. next = data.get("next", next)
  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.using(using).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. except (ValueError, ValidationError), e:
  61. return CommentPostBadRequest(
  62. "Attempting go get content-type %r and object PK %r exists raised %s" % \
  63. (escape(ctype), escape(object_pk), e.__class__.__name__))
  64. # Do we want to preview the comment?
  65. preview = "preview" in data
  66. # Construct the comment form
  67. form = comments.get_form()(target, data=data)
  68. # Check security information
  69. if form.security_errors():
  70. return CommentPostBadRequest(
  71. "The comment form failed security verification: %s" % \
  72. escape(str(form.security_errors())))
  73. # If there are errors or if we requested a preview show the comment
  74. if form.errors or preview:
  75. template_list = [
  76. # These first two exist for purely historical reasons.
  77. # Django v1.0 and v1.1 allowed the underscore format for
  78. # preview templates, so we have to preserve that format.
  79. "comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.module_name),
  80. "comments/%s_preview.html" % model._meta.app_label,
  81. # Now the usual directory based template heirarchy.
  82. "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.module_name),
  83. "comments/%s/preview.html" % model._meta.app_label,
  84. "comments/preview.html",
  85. ]
  86. return render_to_response(
  87. template_list, {
  88. "comment" : form.data.get("comment", ""),
  89. "form" : form,
  90. "next": next,
  91. },
  92. RequestContext(request, {})
  93. )
  94. # Otherwise create the comment
  95. comment = form.get_comment_object()
  96. comment.ip_address = request.META.get("REMOTE_ADDR", None)
  97. if request.user.is_authenticated():
  98. comment.user = request.user
  99. # Signal that the comment is about to be saved
  100. responses = signals.comment_will_be_posted.send(
  101. sender = comment.__class__,
  102. comment = comment,
  103. request = request
  104. )
  105. for (receiver, response) in responses:
  106. if response == False:
  107. return CommentPostBadRequest(
  108. "comment_will_be_posted receiver %r killed the comment" % receiver.__name__)
  109. # Save the comment and signal that it was saved
  110. comment.save()
  111. signals.comment_was_posted.send(
  112. sender = comment.__class__,
  113. comment = comment,
  114. request = request
  115. )
  116. return next_redirect(data, next, comment_done, c=comment._get_pk_val())
  117. comment_done = confirmation_view(
  118. template = "comments/posted.html",
  119. doc = """Display a "comment was posted" success page."""
  120. )