0

The reverse of '‘topic_posts’ works fine in other places. But it doesn’t work here. HTML file

                 <td class="align-middle">
                    {% with post=board.get_last_post %}
                    <small>
                        <a href="{% url 'topic_posts' board.id post.topic.id %}">
                            By {{ post.created_by.username }} at {{ post.created_at }}
                            id - {{ board.id }} {{ post.topic.id }}
                        </a>
                    </small>
                    {% endwith %}
                </td>

url setting

path('boards/<int:board_id>/topics/<int:topic_id>/', views.topic_posts, name='topic_posts'),
    topic = get_object_or_404(Topic, board_id=board_id, id=topic_id)
    return render(request, 'topic_posts.html', {'topic': topic})

When I changed the board.id and post.topic.id to integer value , for exmaple 1 and 24, the web would render. I commented <a href="{% url 'topic_posts' board.id post.topic.id %}"> and added {{ board.id }} {{ post.topic.id }} to see if there is an error with the query, turned out there is no problem, it would render 1, 24 on the webpage. Then I tried <a href="{% url 'topic_posts' board.id 24 %}"> It worked fine, but <a href="{% url 'topic_posts' board.id post.topic.id %}"> still won’t work.

class Board(models.Model):
    name = models.CharField(max_length=30, unique=True)
    description = models.CharField(max_length=100)

    def __str__(self):
        return self.name

    def get_posts_count(self):
        return Post.objects.filter(topic__board=self).count()

    def get_last_post(self):
        return Post.objects.filter(topic__board=self).order_by('-created_at').first()

Thanks for reading!

Wei Wong
  • 65
  • 1
  • 7
  • Is the template code inside a for loop? It seems when `board.id=3` then `post.topic.id` is empty. Which is what the error `(3, '')` is telling you. Can you share the code for `get_last_post`? It's likely this is not returning anything. – Dean Elliott Jun 24 '21 at 12:12
  • Hi, thanks for your reading. I have edited the post. ```{{ post.topic.id }}``` will give me 24 when i commented the `````` – Wei Wong Jun 24 '21 at 12:24
  • Is your template code you have shown inside a for loop? I don't think you are getting `24` for `{{ post.topic.id }}` when `board.id` is `3`. You can check this by printing `print(Post.objects.filter(topic__board_id=3).order_by('-created_at').first())` inside `get_last_post` before the return. This will likely be empty. – Dean Elliott Jun 24 '21 at 12:26
  • This ```id - {{ board.id }} {{ post.topic.id }}``` gives me id - 1 24, which contradict the error ‘(3, ”)’ the error ```board.id ```gives 3 ? – Wei Wong Jun 24 '21 at 12:30
  • Yes, it is inside a for loop – Wei Wong Jun 24 '21 at 12:33
  • You get `1` and `24` fine for the first iteration of the for loop but when the `board.id` is equal to `3` (likely the third iteration), there is no latest post, which is why its empty and throwing an error. – Dean Elliott Jun 24 '21 at 12:34

2 Answers2

0

You have a loop in your template/HTML code. The reason it works for 1 and 24 is because this is the first iteration of the loop and your function get_last_post returns the latest post for a board with the id of 1. But when the for loop finds a board with an id of 3, no latest post exists and is returning None or empty. Which is why you are getting this error. The error is essentially saying, I can't find a URL with only a board_id=3 and an empty post_id.

You can confirm this by printing:

print(Post.objects.filter(topic__board_id=3).order_by('-created_at').first())

or by checking your database for any posts on a board with an id of 3.

You can resolve this by showing the link only if a board with a latest post exists like:

{% if post.topic.id %}
<a href="{% url 'topic_posts' board.id post.topic.id %}">
    By {{ post.created_by.username }} at {{ post.created_at }} id - {{ board.id }} {{ post.topic.id }}
</a>
{% endif %}
Dean Elliott
  • 1,245
  • 1
  • 8
  • 12
0
<a href="{% url 'topic_posts' board.id post.topic.id %}">

Django can't understand board and post here. try to send it through context along with the template during return render

try this:

return render(request, 'topic_posts.html', {'topic': topic, 'board': board, 'post': post})
G.S Dash
  • 78
  • 7
  • Anyway, thanks for your answer. The problem is the for loop. The HTML code I post is inside a for loop. I didn't populate any data for board.id = 3, so post.topic.id gets empty. – Wei Wong Jun 24 '21 at 13:00
  • thank you @WeiWong . Glad to know that your problem solved. – G.S Dash Jun 24 '21 at 13:05