Why DB dont save comment(Django)

Viewed 85

The entered comments in the form are not saved in the database, and are not displayed anywhere. After clicking the save button, it simply redirects to another page and the comments are not displayed. I'm trying to make a form for entering comments directly from the site page, I have already configured it from the administration panel. Thanks!

views.py

class BarbersPage(ListView):
    model = Post
    template_name = 'main/barbers.html' 
    context_object_name = 'posts'

def post_new(request):
    post = get_object_or_404(Post)
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            form.save() 
            return redirect('barbers')
    else:
            form = CommentForm()
    return render(request, 'main/post_detail.html', {'form': form})

barbers.html

{% for post in posts %}
          <img src="{{MEDIA_URL}}{{post.photo.url}}" width="800"  />

          <h3>
        {{ post.name_barber}} 
          </h3>
     <p>{{ post.description}}</p>
     <h3> Comments.. </h3>
   
    {% if not post.comments.all %}
    no comments yet...<a href = "#">Add one</a>

    {% else %}

        {% for comment in post.comments.all %}

    <strong>
        {{ comment.name }}
        {{ comment.add_date }}
    </strong>
        <p>{{comment.body }}</p>
  
        {% endfor %}   
    {% endif %}           
{% endfor %}

post_detail.html

<h1>New comment</h1>
    <form method="POST" class="post-form">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Save</button>
    </form>

urls.py

urlpatterns = [
    path('',views.HomePage.as_view(),name='index'),
    path('barbers/',views.BarbersPage.as_view(), name='barbers'),
    path('post_detail/', views.post_new, name='post_detail'),
  
]

models.py

class Post(models.Model):
    photo       = models.ImageField(upload_to='media/photos/',null=True, blank=True)
    name_barber = models.CharField(max_length=30, null=True, blank=True)
    description = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.description[:10]


class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField(max_length=30)
    body = models.TextField(null=True)
    add_date = models.DateTimeField(auto_now_add=True)


    def __str__(self):
        return '%s - %s' % (self.post, self.name)

forms.py

class CommentForm(ModelForm):
    class Meta:
        model = Comment
        fields = ('name', 'body')
1 Answers

The line

post = get_object_or_404(Post)

in your view function post_new() does not seem correct. The function get_object_or_404() should receive some query params to identify a single Post instance; usually you pass PK or slug as parameters to the function.

Are you sure that no error is raised when submitting your form?


Also, nowhere in your view you are tying your new comment to the Post object, so of course post.comments.all will be empty in your template.

Your view probably needs to look something like this:

def post_new(request, post_id):
    post = get_object_or_404(Post, pk=post_id)

    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False) 
            comment.post = post
            comment.save()

            return redirect('barbers')
    ...

change your urls accordingly:

urlpatterns = [
    ...
    path('post_detail/<int:post_id>/', views.post_new, name='post_detail'),
    ...
]

and don't forget to pass the post_id in the URL when submitting the new comment form.

Related