I'm developing a blog site using Django. My site will allow users to comment on any of my blog posts and also reply to each other and will be displayed using a 'threaded comments' structure (I haven't started user functionality yet, just comments). I've got the threaded comments to work properly using django-mptt (at least, for now), but I have NO CLUE if the route or steps I'm taking are in the right direction. Almost all the tutorials I've gone through only scratch the surface when it comes to comments and doesn't talk about threaded comments in django. I want some experienced/professional advice on what I might be doing wrong and what I could be doing better. The last thing I want is to find out there was a much more acceptable way of going about, after hours of work put in.
So, here is a list of what I need clarity on:
django-mptt:
Multiple forms on one HTML page
I'm sorry if these are noob questions and for my post being so long. I just want to do things the best way possible using realistic solutions for a beginner. Any feedback would help. Thank you! Here's my code for my blog app.
models.py
from django.db import models from mptt.models import MPTTModel, TreeForeignKey class Post(models.Model): """Blog post""" title = models.CharField(max_length=200) body = models.TextField() date_added = models.DateTimeField(auto_now_add=True) def __str__(self): return self.body[:50] + '...' class Comment(MPTTModel): """User comment""" post = models.ForeignKey(Post, related_name='comments',on_delete=models.CASCADE) parent = TreeForeignKey('self', null=True, blank=True, related_name='children',db_index=True, on_delete=models.CASCADE) user_comment = models.CharField(max_length=500, unique=True) date_added = models.DateTimeField(auto_now_add=True) # approved = models.BooleanField(default=False) class MPTTMeta: order_insertion_by = ['date_added'] def __str__(self): return self.user_comment[:20]
'approved' is commented out because I get a 'no such column: approved' error for some weird reason.
forms.py
from django import forms from .models import Post, Comment class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ['user_comment']
views.py
from django.shortcuts import render from django.http import HttpResponseRedirect from django.urls import reverse from .models import Post from .forms import CommentForm def posts(request): """Show all blog posts""" posts = Post.objects.order_by('-date_added') context = { 'posts': posts } return render(request, 'posts/posts.html', context) def post(request, post_id): """Show single blog post""" post = Post.objects.get(id=post_id) comments = post.comments.all() if request.method != 'POST': comment_form = CommentForm() else: comment_form = CommentForm(data=request.POST) try: parent_id = request.POST['comment_id'] except: pass if comment_form.is_valid(): comment = comment_form.save(commit=False) comment.post = post comment.parent = comments.get(id=parent_id) comment.save() return HttpResponseRedirect(reverse('posts:post', args=[post_id])) context = { 'post': post, 'comment_form': comment_form, 'comments': comments, } return render(request, 'posts/post.html', context)
post.html
{% extends 'posts/base.html' %} {% block blog_content %} <h1>Post page!</h1> <h3>{{ post.title }}</h3> <h4>{{ post.date_added }}</h4> <p>{{ post.body }}</p> <form method="post" action="{% url 'posts:post' post.id %}"> {% csrf_token %} {{ comment_form.as_p }} <button type="submit">Add comment</button> </form> {% load mptt_tags %} {% recursetree comments %} <h5>{{ node.date_added }}</h5> <p>{{ node.user_comment }}</p> <form method="post" action="{% url 'posts:post' post.id %}"> {% csrf_token %} {{ comment_form.as_p }} <input type="hidden" name="comment_id" value="{{ node.id }}"> <button type="submit">Reply</button> </form> {% if not node.is_leaf_node %} <div style="padding-left: 20px"> {{ children }} </div> {% endif %} {% endrecursetree %} {% endblock %}
urls.py
from django.urls import path from . import views app_name = 'posts' urlpatterns = [ path('posts/', views.posts, name='posts'), path('posts/<int:post_id>/', views.post, name='post'), ]
Introducing Comment Threads - Keep the Conversation Going Now, when you hit reply underneath any comment, your response will automatically be grouped right underneath it in a thread. To learn more about comment threading, visit the Help Center.
MPTT trees are great for getting a list of subnodes or node counts. They are costly for adding/inserting nodes and the cost increases linearly with the size of the three. They are designed to fit tree data into relational databases. Also, don't get fooled by "I'll have much more reads than writes". Ideally, most of the reads should hit a cache, not the database under it.
Why not skip the relational database and go with a NoSQL database that can natively store trees? There are easy integrations for Django and pretty much every NoSQL database you can thing about.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With