Add comment model to your Django blog website — 2020
In this article, we will see how to add a comment model to the blog app. So readers can send us comments or feedback, it will be easy to do and to manage. Also, we will see how to add the comment count to our view.
Note: I’ll assume you already have models for post and user.
Update the models.py file
The first thing we will do is adding the comment model:
#blog/models.pyclass Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now_add=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE)
content = models.TextField() def __str__(self):
return self.user.username
What did we do?
- We need to define the user of each comment, we use the foreign-key so we create a relationship between the comment and the user model, which we import from django.contrib.auth.models.
- And for sure we need to know when did the user post that comment, we use the DateField, and it will be added automatically.
- Also, each post should have its comments, so we need to set a relationship between the post model and the comment model, we do the same thing as we did with the user model.
- Finally the content of the comment, it’s a simple text field.
Update the admin.py file
Okay, now, To register the Comment model in the admin panel, go to the admin file. import the comment model then register it.
from django.contrib import admin
from blog.models import Category, Author, Post, Comment #newadmin.site.register(Author)
admin.site.register(Category)
admin.site.register(Post)
admin.site.register(Comment) #new
Create forms.py file
If we migrate our app now, you’ll be able to add comments, but the readers can’t. In that case, we create here forms.py file to create a form for our comment model.
from django import forms
from blog.models import Commentclass CommentForm(forms.ModelForm):
content = forms.CharField(widget=forms.Textarea(attrs={
'class': 'md-textarea form-control',
'placeholder': 'comment here ...',
'rows': '4',
})) class Meta:
model = Comment
fields = ('content', )
Explanation:
I’ll use the char field widget because I want to add some attributes to this field, in other words, I will style the content field, so then it looks better on the post page.
And the metaclass to specify what model is working with and which field we want to display.
Update the views.py file
class PostDetailView(HitCountDetailView):
model = Post
template_name = "blog/post.html"
slug_field = "slug"
count_hit = True form = CommentForm def post(self, request, *args, **kwargs):
form = CommentForm(request.POST)
if form.is_valid():
post = self.get_object()
form.instance.user = request.user
form.instance.post = post
form.save() return redirect(reverse("post", kwargs={
'slug': post.slug
})) def get_context_data(self, **kwargs):
post_comments_count = Comment.objects.all().filter(post=self.object.id).count()
post_comments = Comment.objects.all().filter(post=self.object.id)
context = super().get_context_data(**kwargs)
context.update({
'form': self.form,
'post_comments': post_comments,
'post_comments_count': post_comments_count,
})
return context
Migrate the app
Then, we will add our comment model to the database. We have to save the changes by running the makemigrations command line.
$ python manage.py makemigrations blog
Okay, next we need to apply those changes by typing python manage.py migrate blog.
$ python manage.py migrate blog
Edit the post.html file
And we need to add a place in the post template to display the comments, and the form to let readers post their comments.
<!--comments-->
<div class="section ">
<div class="container ">
<h2>Comments({{post_comments_count}})</h2>
<div class="row ">
<div class="col-lg-8 mx-auto ">
<!--display coment--> <div class="media-list">
{% for comment in post_comments %}
<div>
<img class="avatar avatar-sm mr-4" src="https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460__340.png"> <div class="media-body">
<div class="small-1">
<b> {{comment.user}}</b>
<time class="ml-4 opaciy-70 small-3"> {{comment.date}}</time>
</div>
<p> {{comment.content}}</p>
</div>
</div>
{% endfor %}
</div> <!--display the form-->
<form method="POST" action="{% url 'post' slug=post.slug %}">
{% csrf_token %}
<div class="form-group">
{{form}}
</div>
<button class="btn btn-primary btn-block " type="submit">Comment</button>
</form>
</div>
</div>
</div>
</div>
Watch the tutorial on Youtube: https://youtu.be/EaWWJohfwAU