Open In App

Django project to create a Comments System

Last Updated : 24 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

We will build a straightforward Django app where users can view posts and add comments, all using just two simple templates. We will learn how to set up models, handle form submissions and create clean views to power an interactive comment system. It’s perfect for getting a solid foundation with Django’s core features while keeping things neat and minimal.

Set Up Your Django Project and App

Prerequisites:

Open your terminal or command prompt and run:

django-admin startproject comment_project
cd comment_project
python manage.py startapp comments

Explanation:

  • comment_project is your main Django project folder.
  • comments is the app dedicated to handling posts and comments, keeping your code modular and organized.

Configure Your Project Settings

Open comment_project/settings.py and add the comments app to your installed apps:

INSTALLED_APPS = [
# Default Django apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

# Our custom app
'comments',
]

Define Models for Posts and Comments

Edit comments/models.py to add two models: Post and Comment.

Python
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f'Comment by {self.user.username} on "{self.post.title}"'

Explanation:

  • The Post model stores each post's title, content, timestamp and author (linked to Django’s built-in User model).
  • The Comment model links each comment to a Post and a User, stores the comment text and timestamp.
  • related_name='comments' allows you to access comments for a post via post.comments.all().

Create the Database Tables

Run migrations to create the corresponding tables in the database:

python manage.py makemigrations
python manage.py migrate

Register Models with the Admin Interface

Register your models in comments/admin.py to manage posts and comments via the admin panel:

Python
from django.contrib import admin
from .models import Post, Comment

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'date_posted')
    search_fields = ('title', 'content', 'author__username')

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
    list_display = ('post', 'user', 'date_posted')
    search_fields = ('content', 'user__username', 'post__title')

Create a Comment Form

Create comments/forms.py:

Python
from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):
    content = forms.CharField(
        label='',
        widget=forms.Textarea(attrs={
            'rows': 3,
            'placeholder': 'Write your comment here...'
        })
    )

    class Meta:
        model = Comment
        fields = ['content']

Explanation: The form renders a textarea without a label and includes a placeholder for user guidance.

Implement Views

Edit comments/views.py:

Python
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post
from .forms import CommentForm

def home(request):
    posts = Post.objects.all().order_by('-date_posted')
    return render(request, 'comments/home.html', {'posts': posts})

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    comments = post.comments.all().order_by('-date_posted')

    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.user = request.user
            comment.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = CommentForm()

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

Explanation:

  • home fetches all posts ordered by newest first and renders the homepage.
  • post_detail shows a single post with its comments, handles the comment form submission and refreshes the page after posting a comment.

Configure URLs

Create comments/urls.py:

Python
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
]

Include this in your main project URL config comment_project/urls.py:

Python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('comments.urls')),
]

Create Templates

Create the directory structure:

comments/
└── templates/
└── comments/
├── home.html
└── post_detail.html

home.html:

HTML
<!DOCTYPE html>
<html>
<head>
  <title>All Posts</title>
</head>
<body>
  <h1>All Posts</h1>
  <ul>
    {% for post in posts %}
      <li>
        <a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a> by {{ post.author.username }}
      </li>
    {% empty %}
      <li>No posts available.</li>
    {% endfor %}
  </ul>
</body>
</html>

post_detail.html:

HTML
<!DOCTYPE html>
<html>
<head>
  <title>{{ post.title }}</title>
</head>
<body>
  <h1>{{ post.title }}</h1>
  <p>{{ post.content }}</p>
  <p>Posted by {{ post.author.username }} on {{ post.date_posted }}</p>

  <h2>Comments</h2>

  <form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Add Comment</button>
  </form>

  <ul>
    {% for comment in comments %}
      <li><strong>{{ comment.user.username }}</strong>: {{ comment.content }} ({{ comment.date_posted }})</li>
    {% empty %}
      <li>No comments yet.</li>
    {% endfor %}
  </ul>

  <a href="{% url 'home' %}">Back to All Posts</a>
</body>
</html>

Create a Superuser and Run the Server

Create a superuser to add initial posts via the admin panel:

python manage.py createsuperuser

Start the development server:

python manage.py runserver

Visit http://127.0.0.1:8000/admin/ and log in to create posts.

Visit http://127.0.0.1:8000/ to see all posts.

AllPost
All Posts

Click a post title to view and add comments.

AddingCommentOnPost
Adding Comment on Post

Next Article

Similar Reads