0

So i have 2 models,

class Post(models.Model):
    topic = models.CharField(max_length=200)
    description = models.TextField()
    created_by = models.ForeignKey(User, related_name='posts')
    created_on = models.DateTimeField()

    def __str__(self):
        return self.topic

class Comment(models.Model):
    commented_by = models.ForeignKey(User, related_name='comments')
    commented_on = models.ForeignKey(Post, related_name='comments')
    commented_text = models.CharField(max_length=500)
    commented_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.commented_text

and i want to display post and comment on single template. So, i created this view:

def post_desc(request, pk):
    post = get_object_or_404(Post, pk=pk)
    comment_list = Comment.objects.all()
    return render(request, 'post_desc.html', {'post': post, 'comment_list':comment_list})

and try to display them in template:

{% if post.created_on %}
  {{ post.created_on }}
{% endif %}
<h1>{{ post.topic }}</h1>
<p>{{ post.description }}</p>

<h4>Comments</h4>
{% if comment_list.commented_on == post.topic %}
  {{ comment_list.commented_by }}{{ comment_list.commented_text }}
{% endif %}

But it is only displaying post and not comment section. What i did wrong here?

Deepak Rawat
  • 131
  • 2
  • 10
  • 1
    I doubt very much you want to see *all* comments, rather you probably want to see only the ones associated with the current post. – Daniel Roseman Oct 18 '17 at 11:49

2 Answers2

1

You have to iterate the comments.

{% for comment in comment_list %}
  <do your thing>
{% endfor %}

There is one notable issues in the code.

No need to pass all the comments to template. Only pass the comments that belong to the Post.

Sandeep Balagopal
  • 1,943
  • 18
  • 28
  • The related names are ok here - there's no ambiguity between `user.comments.all()` and `post.comments.all()`. – bruno desthuilliers Oct 18 '17 at 12:03
  • wouldn't using different names makes code more readable. Thats what i thought. – Sandeep Balagopal Oct 18 '17 at 12:05
  • This is a question of context. The related names will be used to retrieve associated comments from the _other_ hand of the relationship (in this case from `User` or `Post`) so prefixing the related descriptor name with (resp.) "user_" or "post_" will only add noise for no reason. When you type `user.comments` or `post.comments`, you already know if you're looking comments from a `User` or comments on a `Post`. – bruno desthuilliers Oct 18 '17 at 12:16
  • But it is displaying all comments. How tried this: {% if comment.commented_on == post.topic %} but no result. – Deepak Rawat Oct 18 '17 at 12:19
  • @DeepakRawat go with mohammed qudah answer. You don't have to do that checking at all. Using related name you can retrieve the comments belong to that post only. – Sandeep Balagopal Oct 18 '17 at 12:45
  • @SandeepBalagopal That one is not working, that's why i'm trying this. Any suggestions? – Deepak Rawat Oct 18 '17 at 14:47
  • 1
    If you look into the comments carefully, you can see why it is not working. Instead of post.comment_set.all use post.comments.all – Sandeep Balagopal Oct 19 '17 at 04:10
  • @SandeepBalagopal Yes, it worked. Can you explain me how "post.comments.all" because post and comment are different models. So, how they are working in same query? – Deepak Rawat Oct 19 '17 at 06:43
  • 1
    That is the magic of related name. See https://stackoverflow.com/a/2642645/2282638 – Sandeep Balagopal Oct 19 '17 at 06:44
  • Thanks buddy for the much needed help. I had earlier also read about 'related_names' but i was confused that time about its real use. Now it is clear to me. 1 more thing, do i need to change related names of post and user as you said it makes the code more readable? – Deepak Rawat Oct 19 '17 at 07:27
1

the template code is wrong so the view, your view should be like this:

def post_desc(request, pk):
    post = Post.objects.get(id=pk)
    return render(request, 'post_desc.html', {'post': post})

and the template should be

{% for comment in post.comments.all %}
<p>{{comment.text}}</p>
{% endfor %}

Where comments is the related name to access the Comment objects from Post.

Sandeep Balagopal
  • 1,943
  • 18
  • 28
mohammedgqudah
  • 568
  • 4
  • 15