I cannot post comment in Django, no error

Question:

I’m working on a Django blog and I’m stuck here… I want to post comment and when I do that it just refresh the page and nothing happens.

I have no idea where I’m making a mistake, please see my code below:

this is views.py

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)
    related_posts = post.tags.similar_objects()[:3]
    
    comments = post.comments.filter(active=True)
    new_comment = None
    if request.method == 'POST':
        if request.user.is_authenticated:
            comment_form = CommentForm(data=request.POST)
            if comment_form.is_valid():
                new_comment = comment_form.save(commit=False)
                new_comment.post = post
                new_comment.author = request.user
                new_comment.save()
        else:
            messages.warning(request, 'You need to be logged in to add a comment.')
    else:
        if request.user.is_authenticated:
            comment_form = CommentForm(initial={'author': request.user})
        else:
            comment_form = CommentForm()

    context = {'post': post, 'related_posts': related_posts, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form}
    return render(request, 'post_detail.html', context)

this is comment part post_detail.html

{% if user.is_authenticated %}
<!--comment form-->
<div class="comment-form">
    <h3 class="mb-30">Leave a Reply</h3>
    <form class="form-contact comment_form" action="{% url 'post_detail' post.slug %}" method="post">
        {% csrf_token %}
        <div class="row">
            <div class="col-12">
                <div class="form-group">
                    {{ comment_form | crispy }}
                </div>
            </div>
        </div>
        <div class="form-group">
            <button type="submit" class="button button-contactForm">Post Comment</button>
        </div>
    </form>
</div>
{% else %}
<div class="alert alert-danger" role="alert">
  Please log in to post a comment.
</div>
{% endif %}

this is models.py

class Post(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
    published_at = models.DateTimeField(null=True, blank=True, editable=False, verbose_name="Published at")
    post_title = models.CharField(max_length=200, verbose_name="Title")
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey('auth.User', verbose_name="Author", on_delete=models.CASCADE)
    category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE)
    tags = TaggableManager()
    body = QuillField()
    image = StdImageField(upload_to='featured_image/%Y/%m/%d/', variations={'standard':(1170,820),'banner':(1170,530),'single_post':(1170,556),'thumbnail':(500,500)})
    image_credit = models.CharField(max_length=200, verbose_name="Image credit:")
    status = models.IntegerField(choices=STATUS, default=0)

    def get_absolute_url(self):
        return reverse('post_detail', args=[self.slug])

    def get_readtime(self):
        result = readtime.of_text(self.body)
        return result.text 

    class Meta:
        verbose_name = "Post"
        verbose_name_plural = "Posts"
        ordering = ['-created_at']

    def publish(self):
        self.is_published = True
        self.published_at = timezone.now()
        self.save()

    def __str__(self):
        return self.post_title

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    body = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    active = models.BooleanField(default=False)

    class Meta:
        ordering = ['created_on']

    def __str__(self):
        return 'Comment "{}" by {}'.format(self.body, self.author.username)

this is forms.py

class CommentForm(forms.ModelForm):
    author = forms.CharField(widget=forms.HiddenInput)
    class Meta:
        model = Comment
        fields = ('body', 'user')

Please not that I can post comment over admin page (http://127.0.0.1:8000/admin), but on the front-end doesn’t work for some reason.

Any ideas?

Asked By: Firefoxer

||

Answers:

You need to redirect() after dealing with POST data, the tip is not specific to Django, its a good web practice in general so:

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug)
    related_posts = post.tags.similar_objects()[:3]
    
    comments = post.comments.filter(active=True)
    new_comment = None
    if request.method == 'POST':
        if request.user.is_authenticated:
            comment_form = CommentForm(data=request.POST)
            if comment_form.is_valid():
                new_comment = comment_form.save(commit=False)
                new_comment.post = post
                new_comment.author = request.user
                new_comment.save()
                return redirect(post.get_absolute_url()) # redirect here
        else:
            messages.warning(request, 'You need to be logged in to add a comment.')
    else:
        if request.user.is_authenticated:
            comment_form = CommentForm(initial={'author': request.user})
        else:
            comment_form = CommentForm()

    context = {'post': post, 'related_posts': related_posts, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form}
    return render(request, 'post_detail.html', context)
Answered By: Sunderam Dubey