Django Project: Building a Simple Comment System

3D visualization of speech bubbles hanging in a threaded hierarchy from a main post, representing a Django comment system.

A blog isn’t complete until users can comment. This project will teach you one of Django’s most important concepts: database relationships (ForeignKeys). Building a Django Comment System is a practical way to understand these relationships.

Step 1: The Comment Model

We need a new model that is “linked” to our Post model. Open pages/models.py.

from django.db import models
from django.conf import settings

# ... your Post model ...

class Comment(models.Model):
    # This is the magic!
    # It links each Comment to one Post.
    # 'related_name' lets us do post.comments.all()
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    text = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.text[:50]

Run makemigrations and migrate!

Step 2: The CommentForm

We need a form so users can write a comment. Create pages/forms.py.

# pages/forms.py
from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['text']
        widgets = {
            'text': forms.Textarea(attrs={'rows': 3, 'placeholder': 'Add your comment...'})
        }

Step 3: Update The PostDetailView

Your post_detail.html page must now do two things:

  1. Display existing comments.
  2. Show a form to add a new comment (and handle the POST request).

This is now too complex for a generic DetailView. Let’s use a function-based view in pages/views.py.

# pages/views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post
from .forms import CommentForm
from django.contrib.auth.decorators import login_required

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    comments = post.comments.all()
    
    if request.method == 'POST':
        # This part only runs if the form was submitted
        form = CommentForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False) # Create object, but don't save yet
            new_comment.post = post               # Link it to the post
            new_comment.author = request.user     # Link it to the user
            new_comment.save()                    # Save to database
            return redirect('post_detail', pk=post.pk)
    else:
        # This part runs on a normal GET request
        form = CommentForm()

    return render(request, 'pages/post_detail.html', {
        'post': post,
        'comments': comments,
        'form': form,
    })

(Don’t forget to update your pages/urls.py to use this new function view!)

Step 4: Update The Template

In post_detail.html, add the form and the loop.

<h3>Add a Comment</h3>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Submit</button>
</form>

<h3>Comments</h3>
{% for comment in comments %}
  <p><strong>{{ comment.author }}</strong> on {{ comment.created_at|date:"N j, Y" }}</p>
  <p>{{ comment.text }}</p>
  <hr>
{% empty %}
  <p>No comments yet.</p>
{% endfor %}

Key Takeaways

  • how to create a Django Comment System for user comments on blog posts.
  • First, create a Comment model linked to the Post model in pages/models.py.
  • Next, implement a CommentForm in pages/forms.py for users to write comments.
  • Update PostDetailView to display existing comments and show a form for new comments, using a function-based view.
  • Finally, modify post_detail.html to include the comment form and display comments in a loop.

Similar Posts

Leave a Reply