From df2d635f9169e1f735f89e9c65e5045696806daf Mon Sep 17 00:00:00 2001 From: Greg Thole Date: Sat, 20 Jan 2018 16:27:35 -0500 Subject: [PATCH] Comments save to DB now --- gedgo/admin.py | 9 ++++++- gedgo/forms.py | 27 ++++++++++++------- gedgo/migrations/0003_comment.py | 31 ++++++++++++++++++++++ gedgo/models/__init__.py | 3 ++- gedgo/models/blogpost.py | 2 +- gedgo/models/comment.py | 27 +++++++++++++++++++ gedgo/templates/default/comment_form.html | 10 ++++--- gedgo/views/blog.py | 9 ++++--- gedgo/views/media.py | 1 + gedgo/views/model_views.py | 10 +++---- gedgo/views/util.py | 32 +++++++++-------------- settings.py | 2 +- 12 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 gedgo/migrations/0003_comment.py create mode 100644 gedgo/models/comment.py diff --git a/gedgo/admin.py b/gedgo/admin.py index 3f92f8a..9a1832f 100644 --- a/gedgo/admin.py +++ b/gedgo/admin.py @@ -1,4 +1,4 @@ -from gedgo.models import Gedcom, BlogPost, Document, Documentary +from gedgo.models import Gedcom, BlogPost, Comment, Document, Documentary from django.contrib import admin @@ -7,6 +7,12 @@ class GedcomAdmin(admin.ModelAdmin): filter_horizontal = ('key_families',) +class CommentAdmin(admin.ModelAdmin): + list_display = ('noun', 'user', 'posted') + date_hierarchy = 'posted' + search_fields = ('text', ) + + class BlogPostAdmin(admin.ModelAdmin): list_display = ("title", "created", "body") search_fields = ["title"] @@ -25,6 +31,7 @@ class DocumentaryAdmin(admin.ModelAdmin): admin.site.register(Gedcom, GedcomAdmin) +admin.site.register(Comment, CommentAdmin) admin.site.register(BlogPost, BlogPostAdmin) admin.site.register(Document, DocumentAdmin) admin.site.register(Documentary, DocumentaryAdmin) diff --git a/gedgo/forms.py b/gedgo/forms.py index 7fe2c34..86ca5ee 100644 --- a/gedgo/forms.py +++ b/gedgo/forms.py @@ -4,22 +4,31 @@ from django.shortcuts import get_object_or_404 from django.contrib.auth.models import User -from gedgo.models import Gedcom +from gedgo.models import Gedcom, Comment -class CommentForm(forms.Form): - message = forms.CharField() +class CommentForm(forms.ModelForm): + class Meta: + model = Comment + fields = ('text', 'upload', 'gedcom', 'person', 'blogpost') - def email_comment(self, user, noun, file_names): + def email_comment(self, request): cd = self.cleaned_data - message_body = '%s\n\n%s' % (cd['message'], '\n'.join(file_names)) + content = '%s\n\n---------------\n\n%s' % ( + '%s://%s/admin/gedgo/comment/%s' % ( + 'https' if request.is_secure() else 'http', + request.get_host(), + self.instance.id, + ), + cd['text'] + ) send_mail( 'Comment from %s %s about %s' % ( - user.first_name, - user.last_name, - noun + request.user.first_name, + request.user.last_name, + self.instance.noun ), - message_body, + content, 'noreply@gedgo.com', settings.SERVER_EMAIL ) diff --git a/gedgo/migrations/0003_comment.py b/gedgo/migrations/0003_comment.py new file mode 100644 index 0000000..51b3e7f --- /dev/null +++ b/gedgo/migrations/0003_comment.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2018-01-20 19:09 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('gedgo', '0002_auto_20180120_1030'), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField()), + ('posted', models.DateTimeField(auto_now_add=True)), + ('upload', models.FileField(blank=True, null=True, upload_to=b'uploads/comments')), + ('blogpost', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='gedgo.BlogPost')), + ('gedcom', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='gedgo.Gedcom')), + ('person', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='gedgo.Person')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/gedgo/models/__init__.py b/gedgo/models/__init__.py index a6e54d8..3945ab1 100644 --- a/gedgo/models/__init__.py +++ b/gedgo/models/__init__.py @@ -1,4 +1,5 @@ from gedcom import Gedcom +from comment import Comment from person import Person from family import Family from event import Event @@ -8,6 +9,6 @@ from blogpost import BlogPost __all__ = [ - 'Gedcom', 'Person', 'Family', 'Event', + 'Gedcom', 'Comment', 'Person', 'Family', 'Event', 'Note', 'Document', 'Documentary', 'BlogPost' ] diff --git a/gedgo/models/blogpost.py b/gedgo/models/blogpost.py index d048e93..22bcc01 100644 --- a/gedgo/models/blogpost.py +++ b/gedgo/models/blogpost.py @@ -21,4 +21,4 @@ class Meta: ) def __unicode__(self): - return self.title + return 'Blogpost "%s"' % self.title diff --git a/gedgo/models/comment.py b/gedgo/models/comment.py new file mode 100644 index 0000000..88006ce --- /dev/null +++ b/gedgo/models/comment.py @@ -0,0 +1,27 @@ +from django.db import models +from django.contrib.auth.models import User + + +class Comment(models.Model): + class Meta: + app_label = 'gedgo' + + user = models.ForeignKey(User) + text = models.TextField() + posted = models.DateTimeField(auto_now_add=True) + upload = models.FileField(upload_to='uploads/comments', null=True, blank=True) + + gedcom = models.ForeignKey('Gedcom', null=True, blank=True) + person = models.ForeignKey('Person', null=True, blank=True) + blogpost = models.ForeignKey('BlogPost', null=True, blank=True) + + @property + def noun(self): + if self.blogpost: + return self.blogpost + elif self.person: + return self.person + return self.gedcom + + def __unicode__(self): + return 'Comment about %s by %s (%d)' % (self.noun, self.user, self.id) diff --git a/gedgo/templates/default/comment_form.html b/gedgo/templates/default/comment_form.html index 69421f1..fef5e36 100644 --- a/gedgo/templates/default/comment_form.html +++ b/gedgo/templates/default/comment_form.html @@ -6,13 +6,15 @@

Send us a comment about {{ comment_noun }}.

{% csrf_token %} - +
+ + + {% if show_file_uploads %} - - +

Send us photos or files too if you have any to share. - +

{% endif %}
diff --git a/gedgo/views/blog.py b/gedgo/views/blog.py index 7389efe..8202289 100644 --- a/gedgo/views/blog.py +++ b/gedgo/views/blog.py @@ -48,17 +48,18 @@ def blog_list(request): @login_required def blogpost(request, post_id): - "Single post." + """ + A single post. + """ - noun = "blog post" - form, redirect = process_comments(request, noun) + form, redirect = process_comments(request) if redirect is not None: return redirect context = { 'post': get_object_or_404(BlogPost, id=post_id), 'form': form, - 'comment_noun': noun + 'comment_noun': 'this blog post' } return render( diff --git a/gedgo/views/media.py b/gedgo/views/media.py index cad3e78..b4742e0 100644 --- a/gedgo/views/media.py +++ b/gedgo/views/media.py @@ -16,6 +16,7 @@ STORAGES = { + 'default': default_storage, 'research': research_storage, 'gedcom': gedcom_storage } diff --git a/gedgo/views/model_views.py b/gedgo/views/model_views.py index a0459f7..fa368aa 100644 --- a/gedgo/views/model_views.py +++ b/gedgo/views/model_views.py @@ -11,8 +11,7 @@ def gedcom(request, gedcom_id): g = get_object_or_404(Gedcom, id=gedcom_id) post = BlogPost.objects.all().order_by("-created").first() - noun = g.title or ("Gedcom #%d" % g.id) - form, redirect = process_comments(request, noun) + form, redirect = process_comments(request) if redirect is not None: return redirect @@ -23,7 +22,7 @@ def gedcom(request, gedcom_id): 'gedcom': g, 'post': post, 'form': form, - 'comment_noun': noun + 'comment_noun': str(g) } ) @@ -33,8 +32,7 @@ def person(request, gedcom_id, person_id): g = get_object_or_404(Gedcom, id=gedcom_id) p = get_object_or_404(Person, gedcom=g, pointer=person_id) - noun = "%s (%s)" % (p.full_name, p.pointer) - form, redirect = process_comments(request, noun) + form, redirect = process_comments(request) if redirect is not None: return redirect @@ -44,7 +42,7 @@ def person(request, gedcom_id, person_id): 'photos': [photo for photo in p.photos if not photo.id == p.key_photo.id], 'gedcom': g, 'form': form, - 'comment_noun': noun + 'comment_noun': str(p) } return render(request, 'person.html', context) diff --git a/gedgo/views/util.py b/gedgo/views/util.py index 37a54a9..24a6eae 100644 --- a/gedgo/views/util.py +++ b/gedgo/views/util.py @@ -9,7 +9,8 @@ from gedgo.models import BlogPost, Documentary from gedgo.forms import CommentForm -def process_comments(request, noun): + +def process_comments(request): """ Returns a tuple of (form, redirect_response) depending on whether a new comment has been posted or not. @@ -17,30 +18,23 @@ def process_comments(request, noun): if not request.POST: return CommentForm(), None - form = CommentForm(request.POST) - if form.is_valid(): - # Store file uploads - file_names = [] - if getattr(settings, 'GEDGO_ALLOW_FILE_UPLOADS', True) is True: - for file_ in request.FILES.getlist('uploads'): - upload_path = 'uploaded/%s/%s/%s' % ( - request.user.username, - request.path.strip('/').replace('gedgo/', ''), - file_.name - ) - default_storage.save(upload_path, file_) - file_names.append(upload_path) + form = CommentForm(request.POST, request.FILES) + try: + assert form.is_valid() + form.instance.user = request.user + form.save() + # Email the comment to the site owners. - form.email_comment(request.user, noun, file_names) + form.email_comment(request) messages.success( request, - 'Your comment has ben sent. Thank you!' + 'Your comment has been sent. Thank you!' ) - else: - # Shouldn't happen, since there's almost no server-side validation + except Exception as e: + print e messages.error( request, - "We're sorry, your comment was not sent." + "We're sorry, we couldn't process your comment." ) return None, redirect(request.path) diff --git a/settings.py b/settings.py index a141a66..af2fef6 100644 --- a/settings.py +++ b/settings.py @@ -30,7 +30,7 @@ USE_TZ = True MEDIA_ROOT = '/app/files/default/' -MEDIA_URL = '/gedgo/media/' +MEDIA_URL = '/gedgo/media/default/' STATIC_ROOT = '' STATIC_URL = '/static/'