DEV Community

Suman
Suman

Posted on

Adding Comments In Your Django Project

Utilizing Bootstrap Accordion for adding comments in the UI

In post_view.html:

<p>
  <a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
    Comments : {{post.cmt_count}}
  </a>

</p>
<div class="collapse" id="collapseExample">
 {% for comment in post.comment_set.all %}
  <div class="card card-body">
    {{comment.content}}
  </div>
{% endfor % }
</div>
 <form method="POST">
        {% csrf_token %}
<div class="col-md-8">
              {{ c_form }}
            </div>
 <input type="submit" class="btn btn-secondary" value="Comment"/>
 </form> 
Enter fullscreen mode Exit fullscreen mode

Create a model to link user and post to the comment :

class Comments(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    post = models.ForeignKey(UserPost,on_delete=models.CASCADE)
    content = models.CharField(max_length=500)

    def __str__(self):
        return self.content
Enter fullscreen mode Exit fullscreen mode

*Register your model to the admin site *

from django.contrib import admin
from .models import UserPost,Comments

admin.site.register(Comments)
Enter fullscreen mode Exit fullscreen mode

*Make Migrations : *

python manage.py makemigrations
python manage.py migrate

Enter fullscreen mode Exit fullscreen mode

In case you face operational error delere all migraions folder to restart your database

delete respectively :

  • db.sqlite3

  • in your app/migrations
    delete all files except init

make migrations again, that's it.

Go to the Django admin panel and add some data in them models

Reverse Relationship to get number of comments on a post :

class UserPost(models.Model):
    title = models.CharField(max_length=150,null=False)
    content = models.TextField()
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    image = models.ImageField(upload_to=get_image_path )

    class Meta:
        ordering = ('-created_at',)

    def cmnt_count(self):
        return self.comments_set.all().count()

    def __str__(self):
        return self.title
Enter fullscreen mode Exit fullscreen mode

views.py to render post:

from .forms import PostForm

def post_view(request,pk):
    post = get_object_or_404(UserPost,id=pk)

    context={
        'post':post,
    }
    return render(request,'post_view.html',context)
Enter fullscreen mode Exit fullscreen mode

Include the count as well as Comments on the UI using this reverse mapping

<p>Comments : {{post.cmt_count}}</p>
{% for comment in post.comment_set.all %}
  <div class="card card-body">
    {{comment.content}}
  </div>
{% endfor % }
Enter fullscreen mode Exit fullscreen mode

** Now to let users comment on the post :**

in app/forms.py

from .models import Comments


class CommentForm(forms.ModelForm):
    content = forms.CharField(label="", widget=forms.TextInput(attrs={'placeholder': 'Write Your Thoughts on This Blog','class':'mt-2 focus:ring-1 focus:ring-blue-500'}))

    class Meta:
        model = Comments
        fields = ['content']
Enter fullscreen mode Exit fullscreen mode

in views.py

from .forms import PostForm,CommentForm

def post_view(request,pk):
    post = get_object_or_404(UserPost,id=pk)
    if request.method == "POST":
        if not request.user.is_authenticated:
            messages.warning(request, "Please log in to send a message.")
            login_url = f"{redirect('new_login').url}?{urlencode({'next': request.path})}"  # Preserve return URL
            return redirect(login_url)

        c_form = CommentForm(request.POST)
        if c_form.is_valid():
            instance = c_form.save(commit=False)
            instance.user = request.user
            instance.post = post
            instance.save()
            return redirect('post_view',pk=post.id)
    else:
        c_form = CommentForm()


    context={
        'post':post,
        'c_form':c_form
    }
    return render(request,'post_view.html',context)

Enter fullscreen mode Exit fullscreen mode

Render this form in the UI :

<form method="POST">
        {% csrf_token %}
<div class="col-md-8">
              {{ c_form }}
            </div>
 <input type="submit" class="btn btn-secondary" value="Comment"/>
 </form> 
Enter fullscreen mode Exit fullscreen mode

That's it, Happy Coding you all :)

Top comments (0)