'django.urls.exceptions.NoReverseMatch: Reverse for 'new_entry' with arguments '(1,)' not found. 1 pattern(s) tried: ['new_entry/$']
I am currently working on a tutorial in the "Python Crash course" Book.
The tutorial is about creating a "Learning Log" Webapp with Django. The idea of the app is to allow users to: 1. create "Topics" they have learned about 2. add "Entries" to those Topics, describing details they have learned specific to those topics
I am currently stuck at editing an existing Entry form and receive an Error, when I run http://127.0.0.1:8000/topics/2/
forms.py file
from django import forms
from .models import Topic,Entry
class Topicform(forms.ModelForm):
class Meta:
model = Topic
fields =['text']
labels = {'text' :''}
class Entryform(forms.ModelForm):
class Meta:
model = Entry
fields =['text']
labels = {'text' :''}
widgets = {'text' : forms.Textarea(attrs={'cols':80})}
urls.py file
from django.conf.urls import url
from . import views
app_name='learning_logs'
urlpatterns=[
#Home page
url(r'^$',views.index,name='index'),
#Show all topics page
url(r'^topics/$',views.topics,name='topics'),
#Detail page for a single topic
url(r'^topics/(?P<topic_id>\d+)/$',views.topic,name='topic'),
#Page for adding a new topic
url(r'^new_topic/$',views.new_topic,name='new_topic'),
#Page for adding a new entry
url(r'^new_entry/$',views.new_entry,name='new_entry'),
#Page for editing an entry
url(r'^edit_entry/(?P<entry_id>\d+)/$',views.edit_entry,name='edit_entry'),
]
views.py file
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.shortcuts import render
from .models import Topic,Entry
from .forms import Topicform, Entryform
--snip--
def edit_entry(request,entry_id):
entry = Entry.objects.get(id=entry_id)
topic=entry.topic
if request.method != 'POST':
# No data submitted; create a blank form
form = Entryform(instance = entry)
else:
# Post data submitted;process data
form = Entryform(request.POST,instance=entry)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics',args=[topic.id]))
context={'entry':entry,'topic':topic,'form':form}
return render(request,'learning_logs/edit_entry.html',context)
edit_entry.html file
{% extends "learning_logs/base.html" %}
{% block content %}
<p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
<p>Edit Entry:</p>
<form action= "{%url 'learning_logs:edit_entry' entry.id %}" method = 'post'>
{%csrf_token %}
{{form.as_p}}
<button name="submit">save changes</button>
</form>
{% endblock content %}
topic.html file
{% extends "learning_logs/base.html" %}
{% block content %}
<p> Topic: {{topic}} </p>
<p> Entries:</p>
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}">Add new entry</a>
</p>
<ul>
{%for entry in entries%}
<li>
<p> {{entry.date_added|date:'M d,Y H:i'}} </p>
<p> {{entry.text|linebreaks}} </p>
<p>
<a href="{% url 'learning_logs:edit_entry' entry.id %}">edit entry</a>
</p>
</li>
{%empty%}
<li>
There are no entries for this topic yet.
</li>
{% endfor %}
</ul>
{% endblock content %}
Solution 1:[1]
Your new_entry
path does not take any parameter as from your urls.py
. But you gave one, in topic.html:
<a href="{% url 'learning_logs:new_entry' topic.id %}">Add new entry</a>
Here, topic.id
is what you gave. But should be:
<a href="{% url 'learning_logs:new_entry' %}">Add new entry</a>
EDIT
So, I ll try to explain. Firstly, Let you see the url for new_entry
as you register in urls.py.
#Page for adding a new topic
url(r'^new_topic/$',views.new_topic,name='new_topic'),
Here, you did not gave parameter to the path. See, first part of path. r'^new_topic/$'
. And, see your url route where you gave the parameter:
#Page for editing an entry
url(r'^edit_entry/(?P<entry_id>\d+)/$',views.edit_entry,name='edit_entry'),
Now, let's see the first part r'^edit_entry/(?P<entry_id>\d+)/$'
, here you can see parameter, i.e, (?P<entry_id>\d+)
with name, entry_id. Comparing both the urls, your practical urls will look like:
#For adding new topic
www.example.com/new_topic/
#For url with parameter
www.example.com/edit_entry/1/ # 1 is entry_id, parameter for route edit_entry
Now, lets come in your template:
<a href="{% url 'learning_logs:new_entry' topic.id %}">Add new entry</a>
See, last part in django url tag, i.e, topic.id
. As, in your urls.py you did not give parameter to new_entry. So, if you give parameter to the url which does not take parameter(does not take parameter, I mean to say url is registered but parameter is not set to them), then the url you are getting will be shown.
I hope you now understand what I was saying. For, further more explanation of what to do, you can see the second answer by W-liamx. Have a look at this beautiful documentation on urls by django.
Solution 2:[2]
Adding to Biplove's answer,
In your views.py
file, Your topics
path doesn't take any parameters. May have been a silly typo due to the way you named your urls
So, if you want to return to the list of topics after editing, you should change
return HttpResponseRedirect(reverse('learning_logs:topics',args=[topic.id]))
To
return HttpResponseRedirect(reverse('learning_logs:topics')
But if you want to return to the topic you just edited, you should do this then...
return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 |