Reputation: 21
I'm following along a Django tutorial book to make a basic blogging application where users can write journal entries about whatever topic they choose. I've written the url, pattern, view, and template for my topic page but I keep getting this same error. but I think something is wrong with the url pattern.
urls.py
# Defines url patterns for learning_logs app
from django.conf.urls import url
from . import views
urlpatterns = [
# Home Page
url(r'^$', views.index, name='index'),
# Topic Main Page
url(r'^topics/$', views.topics, name='topics'),
# Detail page for a single topic
url(r"^topics/(?P<topic_id>\d+)/$", views.topics, name='topic'),
]
views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
# This is the home page for our learning_logs app
return render(request, 'learning_logs/index.html')
# This is the view for 'topics' page 9.5.20
def topics(request, topic_id):
'''show a single topic and 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/topics.html', context)
And the error: TypeError: topics() missing 1 required positional argument: 'topic_id'
Any advice? Thank you.
EDIT**
What I'm trying to do is to have a page that lists all of the topics in general. When the link for one topic in particular is clicked, it will lead to the page for that particular topic.
Here's the code for the topics.html (all topics displayed) and topic.html (when one particular topic is chosen)..
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 %}
and 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, YH:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
</li>
{% empty %}
<li>No topics have been added yet</li>
{% endfor %}
</ul>
{% endblock content %}
Upvotes: 0
Views: 794
Reputation: 359
The error clearly specifies that the function is not getting "topic_id", so there can be two cases
path('topics/<int:topic_id>/', views.topics, name='topics'),
Lastly do not follow tutorial word to word because of things changes with update.
Upvotes: 1
Reputation: 3395
Your view is expecting a parameter passed to it ...
def topics(request, topic_id):
But your url does not have one:
url(r'^topics/$', views.topics, name='topics'),
You need to change the url to be something like:
path('topics/<int:topic_id>/', views.topics, name='topics'),
This means you would access that specific record at the url:
yourdomain.com/topics/1/
The 1
would be passed to the view, and used in topic = Topic.objects.get(id=topic_id)
The fact that you also have the url:
url(r'^topics/$', views.topics, name='topics'),
confuses matters - what is this view going to show with no topic set? From your code I suspect you want a list view here, which should ideally link to a different view, and maybe be named topics-list
for clarity and ease of access in reverse lookups later. Your topics
view specifically states in the docstring it is for viewing a single record, so don'ttry and use it for multiple ones as well. Much simpler to create a distinct view for that.
Edit: I see you've updated your path in urls.py
in the question now. That should work for the single access, but note that your link topics/
is still directing to the same view - i.e. it's looking for a single record, but you're not telling it which.
Upvotes: 0