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_projectis your main Django project folder.
- commentsis the app dedicated to handling posts and comments, keeping your code modular and organized.
Configure Your Project Settings
Opencomment_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
Editcomments/models.py to add two models: Post and Comment.
Pythonfromdjango.dbimportmodelsfromdjango.contrib.auth.modelsimportUserfromdjango.utilsimporttimezoneclassPost(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):returnself.titleclassComment(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):returnf'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 incomments/admin.py to manage posts and comments via the admin panel:
Pythonfromdjango.contribimportadminfrom.modelsimportPost,Comment@admin.register(Post)classPostAdmin(admin.ModelAdmin):list_display=('title','author','date_posted')search_fields=('title','content','author__username')@admin.register(Comment)classCommentAdmin(admin.ModelAdmin):list_display=('post','user','date_posted')search_fields=('content','user__username','post__title')
Create a Comment Form
Create comments/forms.py:
Pythonfromdjangoimportformsfrom.modelsimportCommentclassCommentForm(forms.ModelForm):content=forms.CharField(label='',widget=forms.Textarea(attrs={'rows':3,'placeholder':'Write your comment here...'}))classMeta:model=Commentfields=['content']
Explanation: The form renders a textarea without a label and includes a placeholder for user guidance.
Implement Views
Editcomments/views.py:
Pythonfromdjango.shortcutsimportrender,get_object_or_404,redirectfrom.modelsimportPostfrom.formsimportCommentFormdefhome(request):posts=Post.objects.all().order_by('-date_posted')returnrender(request,'comments/home.html',{'posts':posts})defpost_detail(request,pk):post=get_object_or_404(Post,pk=pk)comments=post.comments.all().order_by('-date_posted')ifrequest.method=='POST':form=CommentForm(request.POST)ifform.is_valid():comment=form.save(commit=False)comment.post=postcomment.user=request.usercomment.save()returnredirect('post_detail',pk=post.pk)else:form=CommentForm()returnrender(request,'comments/post_detail.html',{'post':post,'comments':comments,'form':form,})
Explanation:
- homefetches all posts ordered by newest first and renders the homepage.
- post_detailshows a single post with its comments, handles the comment form submission and refreshes the page after posting a comment.
Configure URLs
Createcomments/urls.py:
Pythonfromdjango.urlsimportpathfrom.importviewsurlpatterns=[path('',views.home,name='home'),path('post/<int:pk>/',views.post_detail,name='post_detail'),]
Include this in your main project URL configcomment_project/urls.py:
Pythonfromdjango.contribimportadminfromdjango.urlsimportpath,includeurlpatterns=[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><ahref="{% 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><formmethod="POST"> {% csrf_token %} {{ form.as_p }}<buttontype="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><ahref="{% 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
Visithttp://127.0.0.1:8000/admin/ and log in to create posts.
Visithttp://127.0.0.1:8000/ to see all posts.
All PostsClick a post title to view and add comments.
Adding Comment on PostCreating Comment Model in Django