NoReverseMatch problem with my tutorial for Django

Viewed 97

Going through the Django Tutorial in Python Crash Course and am facing a wall. The error I get is 'Reverse for 'topic' with arguments '('',)' not found. 1 pattern(s) tried: ['topics/(?P<topic_id>\\d+)/$']'.

This is my urls.py

from django.conf.urls import URL


from . import views


urlpatterns = [
# the actual url patter is a call to the url () function, which takes three arguments
# Home page
url(r'^$', views.index, name='index'),

#Show all topics 
url(r'^topics/$', views.topics, name='topics'),

# Detail page for a single topic
url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'),

]

app_name= 'learning_logs'

views.py from django.shortcuts import render

from .models import Topic

def index(request):
"""The home page for Learning Log"""
    return render(request, 'learning_logs/index.html')

def topics(request):
"""Show all topics."""
    topics = Topic.objects.order_by('date_added')
    context = {'topics' :  topics}
    return render(request, 'learning_logs/topics.html', context)

def topic(request, topic_id):
    """Show a single topic and all its entries."""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context) 

topic.html {%extends 'learning_logs/base.html' %}

{%block content%}
<p>Topic: {{topic}}</p>
<p>Entries:</p>
<ul>
    {% for entry in entries %}
        <li>
            <p>{{entry.date_added|date:'M d, Y H:i'}}</p>
            <p>{{entry.text| linebreaks}}</p>
        </li>
    {% empty %}
        <li>
            There are no entries for this topic yet.
        </li>
    {% endfor %}
    </ul>

{%endblock content%}

I've read through some of the Django documentation but I'm not comprehending enough to solve this problem on my own. If I need to add some more code to help please let me know. All help is really appreciated.

Edit: Topics.html

{%extends 'learning_logs/base.html'%}

{% block content%}

<p>Topics</p>
<ul>
    {%for topic in topics%}
        <li>
            <a href="{% url 'learning_logs:topic' topic_id%}">{{topic}}</a>
        </li>
    {%empty%}
        <li>No topics have been added yet</li>
    {%endfor%}
</ul>

{% endblock content%}
2 Answers

The problem is in topics.html. Here's the loop that shows each topic:

    {%for topic in topics%}
        <li>
            <a href="{% url 'learning_logs:topic' topic_id%}">{{topic}}</a>
        </li>
    {%empty%}
        <li>No topics have been added yet</li>
    {%endfor%}

The variable topic_id is not defined. That should be topic.id, which accesses the id attribute of topic.

In your template you are trying to access topic but in views.py you didn't pass topic variable to context. pass topic in your context variable:

def topic(request, topic_id):
    """Show a single topic and all its entries."""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries, 'topic': topic}
    return render(request, 'learning_logs/topic.html', context) 
Related