django displaying posts and comments
Question:
this is models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
date = models.DateTimeField(default=timezone.now)
def write(self):
self.date = timezone.now()
self.save()
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('humorge.post', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=100)
content = models.TextField()
date = models.DateTimeField(default=timezone.now)
def add_coment(self):
self.date = timezone.now()
self.save()
def __str__(self):
return self.content
and this is views.py
def mainpage(request):
return render(request, 'index.html')
def post(request):
datas = Post.objects.order_by('-date')
comments = Comment.objects.all()
return render(request, 'post.html', {'datas': datas, 'comments': comments})
and this is template
{% extends 'layout.html' %}
{% block main %}
<div class="container">
{% for data in datas %}
<div class="row">
<div class="col s12 m7">
<div class="card">
<div class="card-image">
<img src="#">
<span class="card-title">{{ data.title }}</span>
</div>
<div class="card-content">
<p>{{ data.content }}</p>
</div>
<div class="card-action">
<p>{{ data.date }}</p>
</div>
<div class="card-action">
{% for comment in comments %}
{% if comment.post == data.title %}
{{ comment.date }}<br>
<strong>{{ comment.author }}</strong>
<p>{{ comment.content }}</p>
{% endif %}
{% empty %}
<p>There is no comments</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% empty %}
<p>there is no posts</p>
{% endfor %}
</div>
{% endblock %}
I want to display posts and comments
when I try to have two posts and each post has one comments
it shows like each posts has two comments
so I added {% if comment.post == data.title %}
in the template
but it shows nothing
I tried to find answers on google, youtube, some tutorial page….
but what I found was just how to add comments on posts..
or displaying post and comment but actually one post one comment
Answers:
You don’t need to query list of comments in you views, you need just posts:
def post(request):
datas = Post.objects.order_by('-date')
return render(request, 'post.html', {'datas': datas})
And in template you can then do something like this:
{% block main %}
<div class="container">
{% for data in datas %}
...
<div class="card-action">
{% for comment in data.comments.all %} // Gives list of all comments for the current post ie. data
{{ comment.date }}<br>
<strong>{{ comment.author }}</strong>
<p>{{ comment.content }}</p>
{% empty %}
<p>There is no comments</p>
{% endfor %}
</div>
{% empty %}
<p>there is no posts</p>
{% endfor %}
</div>
...
{% endblock %}
Btw the thing that’s wrong with the if condition in your template is that you are doing {% if comment.post == data.title %}
but commpent.post
is an object of model Post
and post.title
is string, so they are never equal. What you need to do is {% if comment.post == data %}
or {% if comment.post.title == data.title %}
In your post view, instead of:
comment = Comment.objects.all()
which will fetch all the comments irrespective of the post it belongs to,
do this:
comment = datas.comments.all()
where the ‘comments’ is the related_name declared in the post field of the Comment model.
this is models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
date = models.DateTimeField(default=timezone.now)
def write(self):
self.date = timezone.now()
self.save()
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('humorge.post', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=100)
content = models.TextField()
date = models.DateTimeField(default=timezone.now)
def add_coment(self):
self.date = timezone.now()
self.save()
def __str__(self):
return self.content
and this is views.py
def mainpage(request):
return render(request, 'index.html')
def post(request):
datas = Post.objects.order_by('-date')
comments = Comment.objects.all()
return render(request, 'post.html', {'datas': datas, 'comments': comments})
and this is template
{% extends 'layout.html' %}
{% block main %}
<div class="container">
{% for data in datas %}
<div class="row">
<div class="col s12 m7">
<div class="card">
<div class="card-image">
<img src="#">
<span class="card-title">{{ data.title }}</span>
</div>
<div class="card-content">
<p>{{ data.content }}</p>
</div>
<div class="card-action">
<p>{{ data.date }}</p>
</div>
<div class="card-action">
{% for comment in comments %}
{% if comment.post == data.title %}
{{ comment.date }}<br>
<strong>{{ comment.author }}</strong>
<p>{{ comment.content }}</p>
{% endif %}
{% empty %}
<p>There is no comments</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% empty %}
<p>there is no posts</p>
{% endfor %}
</div>
{% endblock %}
I want to display posts and comments
when I try to have two posts and each post has one comments
it shows like each posts has two comments
so I added {% if comment.post == data.title %}
in the template
but it shows nothing
I tried to find answers on google, youtube, some tutorial page….
but what I found was just how to add comments on posts..
or displaying post and comment but actually one post one comment
You don’t need to query list of comments in you views, you need just posts:
def post(request):
datas = Post.objects.order_by('-date')
return render(request, 'post.html', {'datas': datas})
And in template you can then do something like this:
{% block main %}
<div class="container">
{% for data in datas %}
...
<div class="card-action">
{% for comment in data.comments.all %} // Gives list of all comments for the current post ie. data
{{ comment.date }}<br>
<strong>{{ comment.author }}</strong>
<p>{{ comment.content }}</p>
{% empty %}
<p>There is no comments</p>
{% endfor %}
</div>
{% empty %}
<p>there is no posts</p>
{% endfor %}
</div>
...
{% endblock %}
Btw the thing that’s wrong with the if condition in your template is that you are doing {% if comment.post == data.title %}
but commpent.post
is an object of model Post
and post.title
is string, so they are never equal. What you need to do is {% if comment.post == data %}
or {% if comment.post.title == data.title %}
In your post view, instead of:
comment = Comment.objects.all()
which will fetch all the comments irrespective of the post it belongs to,
do this:
comment = datas.comments.all()
where the ‘comments’ is the related_name declared in the post field of the Comment model.