djangodjango-urlsdjango-url-reverse

Django: Reverse for ‘topic_posts’ with arguments ‘(3, ”)’ not found


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!


Solution

  • 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 %}