diff options
author | luxagraf <sng@luxagraf.net> | 2019-05-05 11:40:42 -0500 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2019-05-05 11:40:42 -0500 |
commit | a2891841fbf1e5660693a1f9109f2e6810224a3b (patch) | |
tree | be0aae73fe8f5e6271a76e8c5c6dc35b00f347a6 /app/django_comments/views/comments.py | |
parent | bdc06f56d538358f1fa07d35afb5733c790e3ab2 (diff) |
Diffstat (limited to 'app/django_comments/views/comments.py')
-rw-r--r-- | app/django_comments/views/comments.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/app/django_comments/views/comments.py b/app/django_comments/views/comments.py new file mode 100644 index 0000000..40dfc60 --- /dev/null +++ b/app/django_comments/views/comments.py @@ -0,0 +1,140 @@ +from __future__ import absolute_import + +from django import http +from django.apps import apps +from django.conf import settings +from django.contrib.sites.shortcuts import get_current_site +from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.shortcuts import render +from django.template.loader import render_to_string +from django.utils.html import escape +from django.views.decorators.csrf import csrf_protect, csrf_exempt +from django.views.decorators.http import require_POST + +import django_comments +from django_comments import signals +from django_comments.views.utils import next_redirect, confirmation_view + + +class CommentPostBadRequest(http.HttpResponseBadRequest): + """ + 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. + """ + + def __init__(self, why): + super(CommentPostBadRequest, self).__init__() + if settings.DEBUG: + self.content = render_to_string("comments/400-debug.html", {"why": why}) + + +@csrf_exempt +@require_POST +def post_comment(request, next=None, using=None): + """ + Post a comment. + + HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are + errors a preview template, ``comments/preview.html``, will be rendered. + """ + # Fill out some initial data fields from an authenticated user, if present + data = request.POST.copy() + try: + user_is_authenticated = request.user.is_authenticated() + except TypeError: # Django >= 1.11 + user_is_authenticated = request.user.is_authenticated + if user_is_authenticated: + if not data.get('name', ''): + data["name"] = request.user.get_full_name() or request.user.get_username() + if not data.get('email', ''): + data["email"] = request.user.email + + # 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.") + try: + model = apps.get_model(*ctype.split(".", 1)) + target = model._default_manager.using(using).get(pk=object_pk) + 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)) + except ObjectDoesNotExist: + return CommentPostBadRequest( + "No object matching content-type %r and object PK %r exists." % ( + escape(ctype), escape(object_pk))) + except (ValueError, ValidationError) as e: + return CommentPostBadRequest( + "Attempting go get content-type %r and object PK %r exists raised %s" % ( + escape(ctype), escape(object_pk), e.__class__.__name__)) + + # Do we want to preview the comment? + preview = "preview" in data + + # Construct the comment form + form = django_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 = [ + # 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.model_name), + "comments/%s_preview.html" % model._meta.app_label, + # Now the usual directory based template hierarchy. + "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.model_name), + "comments/%s/preview.html" % model._meta.app_label, + "comments/preview.html", + ] + return render(request, template_list, { + "comment": form.data.get("comment", ""), + "form": form, + "next": data.get("next", next), + }, + ) + + # Otherwise create the comment + comment = form.get_comment_object(site_id=get_current_site(request).id) + comment.ip_address = request.META.get("REMOTE_ADDR", None) or None + if user_is_authenticated: + comment.user = request.user + + # Signal that the comment is about to be saved + responses = signals.comment_will_be_posted.send( + sender=comment.__class__, + comment=comment, + request=request + ) + + for (receiver, response) in responses: + if response is False: + return CommentPostBadRequest( + "comment_will_be_posted receiver %r killed the comment" % receiver.__name__) + + # Save the comment and signal that it was saved + comment.save() + signals.comment_was_posted.send( + sender=comment.__class__, + comment=comment, + request=request + ) + + return next_redirect(request, fallback=next or 'comments-comment-done', + c=comment._get_pk_val()) + + +comment_done = confirmation_view( + template="comments/posted.html", + doc="""Display a "comment was posted" success page.""" +) |