Reputation: 85
I have trouble with adding comments to my django web-application. I want to add comments to allow users comment posts, like in normal web blog. I've tried a few ways, but nothing worked correctly for me.
After a few weeks searching and trying different ways to solve this question, I've stacked on this question. I have some progress, but it's now what I want completely.
Now I can only add "comments" from admin panel
and it look like this (from admin panel)
and like this (from user interface)
And I have this issue with padding comments( I don't really understand why it's occurs ¯_(ツ)_/¯ )
Anyway, here is my code, hope someone know how to solve this problem:
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.text
...
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
categories = models.ManyToManyField('Category', related_name='posts')
image = models.ImageField(upload_to='images/', default="images/None/no-img.jpg")
slug= models.SlugField(max_length=500, unique=True, null=True, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'slug': self.slug})
post_detail.html
<article class="media content-section">
{% for comment in post.comments.all %}
<ul>
{{ comment.text }}
{% for reply in comment.replies.all %}
<li>
{{ reply.text }}
</li>
{% endfor %}
<ul>
{% endfor %}
</article>
I also read this article about creation blog for beginners, and they have working comment section as I want, but I tried to implement their code to my web-app, and nothing worked for me.
They have comment section like this (I need completely the same one):
But when I tried to follow their tutorial, I have only like this:
And here is the code for this unsuccessful solution( but I feel like it is working one, maybe I did something wrong)
post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.image.url }}" alt="">
<div class="article-metadata">
<a class="mr-2 author_title" href="{% url 'user-posts' object.author.username %}">@{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"N d, Y" }}</small>
<div>
<!-- category section -->
<small class="text-muted">
Categories:
{% for category in post.categories.all %}
<a href="{% url 'blog_category' category.name %}">
{{ category.name }}
</a>
{% endfor %}
</small>
</div>
{% if object.author == user %}
<div>
<a class='btn btn-secondary btn-sm mt-1 mb-1' href="{% url 'post-update' object.slug %}">Update</a>
<a class='btn btn-danger btn-sm mt-1 mb-1' href="{% url 'post-delete' object.slug %}">Delete</a>
</div>
{% endif %}
</div>
</article>
<article class="media content-section">
<div class="media-body">
<img class="img-fluid center" id="rcorners3" src="{{ object.image.url }}" alt="none">
<h2 class="article-title text-center">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
<article class="media content-section">
<form action="/blog/{{ post.pk }}/" method="post">
{% csrf_token %}
<div class="form-group">
{{ form.author }}
</div>
<div class="form-group">
{{ form.body }}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<h3>Comments:</h3>
{% for comment in comments %}
<p>
On {{comment.created_on.date }}
<b>{{ comment.author }}</b> wrote:
</p>
<p>{{ comment.body }}</p>
<hr>
{% endfor %}
</article>
{% endblock content %}
views.py
...
def comment(request):
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment(
author=form.cleaned_data["author"],
body=form.cleaned_data["body"],
post=post
)
comment.save()
comments = Comment.objects.filter(post=post)
context = {
"post": post,
"comments": comments,
"form": form,
}
models.py
...
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.text
forms.py
from django import forms
class CommentForm(forms.Form):
author = forms.CharField(
max_length=60,
widget=forms.TextInput(attrs={
"class": "form-control",
"placeholder": "Your Name"
})
)
body = forms.CharField(widget=forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Leave a comment!"
})
)
Upvotes: 0
Views: 165
Reputation: 935
You are creating unnecessary lists. Try this one
<article class="media content-section">
<ul>
{% for comment in post.comments.all %}
<li>{{ comment.text }}</li>
{% if comment.replies.all %}
<ul>
{% for reply in comment.replies.all %}
<li>{{ reply.text }}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
<ul>
</article>
Upvotes: 1