Cannot resolve NoReverseMatch error in Django - python

I am new in Django and try to make a quick search engine, but I have this error and cannot fix it after reading Django documentation. Could anyone help me? Thanks.
This is the error:
Reverse for 'search' with no arguments not found. 1 pattern(s) tried: ['(?P<name>[^/]+)$']
My codes are as below:
layout.html
<form method="POST" action="{% url 'encyclopedia:search' %}">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
<input type="submit" value="Go">
</form>
urls.py
from django.urls import path
from . import views
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("<str:name>", views.entry, name="entry"),
path("<str:name>", views.search, name="search")
]
views.py
def search(request, searched_name):
"""
Deal with search engine on the left widget
"""
result = util.get_entry(searched_name)
if result:
return HttpResponseRedirect(reverse('encyclopedia:entry', args=(result)))
return render(request, "encyclopedia/error.html", {
"error_name": "Requested page not found"
})

Your second and third urls the same that's why only one pattern is tried and given the pattern named search isn't the first one, django is unable to find a reverse match. The URLs aren't well thought as they will both match any string after the root of the domain and this will definitely become a nightmare as your project grows bigger. Consider having them as below:
urlpatterns = [
...
path("entry/<str:name>", views.entry, name="entry"),
path("search/<str:name>", views.search, name="search")
]

As per your urls.py, you need to name in URL itself.
I will suggest you to remove name from urls.py and get in views via form data. Please see an example below
urls.py -> path("search/", views.search, name="search")
def search(request):
"""
Deal with search engine on the left widget
"""
result = util.get_entry(request.POST.get('q', None))
if result:
return HttpResponseRedirect(reverse('encyclopedia:entry', args=(result)))
return render(request, "encyclopedia/error.html", {
"error_name": "Requested page not found"
})

Related

redirect errot - NoReverseMatch: Reverse for 'edit' with keyword arguments '{'title': 'Python'}' not found

I'm working on an app that allows the user to create, show and edit an entry. right now i'm working on the editing function. what i'm trying to do is have an edit button (that's actually a form that sends data via hidden inputs) that sends the title of the entry to a view called trans whose sole purpose is redirect to the edit view, the reason i did this is so that when i'm working on the edit view, i can simplify the process where if the request method is GET it shows the page with the form where the user can edit the entry and if it's post the edit view can receive the changes and save them without worrying about the redirecting from the entry's page.
The problem lies in the fact that everytime i click the edit button i get the error:
NoReverseMatch at /wiki/trans
Reverse for 'edit' with keyword arguments '{'title': 'Python'}' not found.
I have checked over and over for any misspellings or issues in urls.py or any problems with the naming but i just can't find the bug. and it's frustrating because i thought that this would be the easiest part of the project.
Below is the relevant code. i would be extremely grateful for anyone who points out what i'm doing wrong. Thank you in Advance.
HTML
<div id="edit">
<form action="{% url 'wiki:trans' %}" method="POST">
{% csrf_token %}
<input type=hidden value={{title}} name="title">
<input type=submit value="Edit">
</form>
</div>
views.py
class EntryForm(forms.Form):
title = forms.CharField(label="Title")
content = forms.CharField(widget=forms.Textarea)
def trans(request):
title = request.POST.get("title")
return redirect("wiki:edit", title=title)
def edit(request, title):
if request.method == "GET":
entry = util.get_entry(title)
return render(request, "encyclopedia/edit.html", {
"form": EntryForm({
"content": entry,
"title": title
})
})
else:
form = EntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return redirect("wiki:title", title=title)
urls.py
app_name = "wiki"
urlpatterns = [
path("", views.index, name="index"),
path("search", views.search, name="search"),
path("new", views.new, name="new"),
path("trans", views.trans, name="trans"),
path("edit", views.edit, name="edit"),
path("random", views.rand, name="random"),
path("<str:title>", views.title, name="title")
]
Try adding a / at the end of each url, like this:
urls.py:
app_name = "wiki"
urlpatterns = [
path("", views.index, name="index"),
path("search/", views.search, name="search"),
path("new/", views.new, name="new"),
path("trans/", views.trans, name="trans"),
path("edit/", views.edit, name="edit"),
path("random/", views.rand, name="random"),
path("<str:title>/", views.title, name="title")
]
Also try using reverse and passing in the title as an arg on your views.py:
return redirect(reverse('wiki:title', args=[title]))

Cannot fix Django NoReverseMatch error despite URL being withing urls.py

Before I go into detail, here is the line from the html document that results in the error, as well as views.py and urls.py:
<input class="search" type="text" name="q" placeholder="Search Encyclopedia" action="{% url 'encyclopedia:findpage' %}" method="get">
(Yes there is a space betweeen url and 'encyclopedia:findpage')
views.py findpage function:
def findpage(request, name):
pages = util.list_entries()
wanted_pages = set()
wanted_page = None
for page in pages:
if not wanted_page and page == name:
wanted_page = util.get_entry(name)
continue
if name in page:
wanted_pages.add(page)
if wanted_page:
return render(request, 'encyclopedia/page.html', {
"title": name,
"entry": wanted_page
})
if wanted_pages and not wanted_page:
return render(request, 'encyclopedia/index.html', {
"entries": wanted_pages
})
else:
return render(request, 'encyclopedia/noresults.html')
urls.py:
from django.urls import path
from . import views
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("<str:name>", views.wikipage, name="wikipage"),
path("<str:name>", views.findpage, name='findpage'),
path("create", views.newpage, name="newpage")
]
When I run the Django project, I get a NoReverseMatch at /. The error from the webpage reads:
In template /home/quinn/Desktop/cs50web/pset1/wiki/encyclopedia/templates/encyclopedia/layout.html, error at line 17 Reverse for 'findpage' with no arguments not found. 1 pattern(s) tried: ['(?P<name>[^/]+)$']
Line 17 is the piece of html I left at the top of this page. I've checked numerous sources in an attempt to fix this, but I cannot figure it out.
You need to specify a name because your url needs it here:
path("<str:name>", views.findpage, name='findpage')
You can specify kwargs in the url tag in your template like this:
{% url 'reverse:lookup' kwarg='insert here the value that needs to get passed in your url' %}

Page Not Found Error occured while trying to render form in django

I've been following the instructions here.
This is the error it gives me, when i try to run it on localhost:
Page not found (404)
Request Method: GET
Request URL: http://localhost:7000/account.html
Using the URLconf defined in gettingstarted.urls, Django tried these URL patterns, in this
order:
[name='index']
[name='account']
db/ [name='db']
admin/
^celery-progress/
The current path, account.html, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change
that to False, and Django will display a standard 404 page.
This is what i have in my urls.py
urlpatterns = [
path("", hello.views.index, name="index"),
path("", hello.views.account, name="account"),
path("db/", hello.views.db, name="db"),
path("admin/", admin.site.urls),
re_path(r'^celery-progress/', include('celery_progress.urls'))
]
This is what i have in views.py
def account(request):
if request.method == 'POST':
form = AccountForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('loading.html')
else:
form = Nameform()
return render(request, 'account.html', {'form': form})
Finally this is the form itself(account.html):
<form action="/account/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
I have the feeling i'm missing something really simple but i can't for the life of me see it. Any help would be greatly appreciated.
First, you need to change the URL patterns, because multiple views (hello.views.index and hello.views.account) are pointing towards the same pattern
urlpatterns = [
path("index/", hello.views.index, name="index"),
path("account/", hello.views.account, name="account"),
path("db/", hello.views.db, name="db"),
path("admin/", admin.site.urls),
re_path(r'^celery-progress/', include('celery_progress.urls'))
]
then, access the URL, http://localhost:7000/account/
You are requesting for the url that could match the string /account/ but in your urlpatterns variable you have an empty string so it can't match anything.
Remember that the first argument of urlpatterns is a pattern string that can be matched with regex.
Perhaps you could map it like:
path("/account/", hello.views.account, name="account")

Django URL error when using forms

I am fairly new to Django and I am totally stuck on what is causing this error. I have done lots of searching but to no avail! Any help would be super appreciated.
The actual form works fine but when I try and submit the input data I get the error:
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^admin/
^$ [name='home']
^patientlist [name='patient_list']
^patientdetail/(?P<pk>\d+)/$ [name='patient_detail']
^add_patient/$ [name='add_patient']
The current URL, spirit3/add_patient/, didn't match any of these.
My urls.py in the mysite directory looks like:
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('spirit3.urls')),
]
My urls.py in the app looks like:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^patientlist', views.patient_list, name='patient_list'),
url(r'^patientdetail/(?P<pk>\d+)/$', views.patient_detail, name='patient_detail'),
url(r'^add_patient/$', views.add_patient, name='add_patient'),
]
The relevant part of views.py:
def add_patient(request):
if request.method == 'POST':
form = PatientForm(request.POST)
if form.is_valid():
form.save(commit=True)
return redirect('home')
else:
print form.errors
else:
form = PatientForm()
return render(request, 'spirit3/add_patient.html', {'form':form})
And the html looks like:
{% extends 'spirit3/base.html' %}
{% block content %}
<body>
<h1> Add a Patient </h>
<form action="/spirit3/add_patient/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Create Patient" />
</form>
</body>
{% endblock %}
Thanks in advance! :)
the form "action" attribute is wrong... seeing your urls configuration you dont have a /spirit3/add_patient/ url, I think It is /add_patient/
or you could just use a form tag without an "action" it will post to the current page:
<form role="form" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Create Patient" />
</form>
Hope this helps
As pleasedontbelong mentionned, there's indeed no url matching "/spirit3/add_patient/" in your current url config. What you have in tour root urlconf is:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('spirit3.urls')),
]
This means that urls with path starting with "/admin/" are routed to admin.site.urls, and all other are routed to spirit3.urls. Note that this does NOT in any way prefixes urls defined in spirit3.urls with '/spirit3/', so in your case, all of these urls:
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^patientlist', views.patient_list, name='patient_list'),
url(r'^patientdetail/(?P<pk>\d+)/$', views.patient_detail, name='patient_detail'),
url(r'^add_patient/$', views.add_patient, name='add_patient'),
]
will be served directly under the root path "/" - ie, the add_patient view is served by "/add_patient/", not by "/spirit3/add_patient/".
If you want your spirit3 app's urls to be routed under "/spirit3/*", you have to specify this prefix in your root urlconf, ie:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^spirit3/', include('spirit3.urls')),
]
Note that you can use any prefix, it's totally unrelated to your app name.
As a last note: never hardcode urls anywhere, django knows how to reverse an url from it's name (and args / kwargs if any). In a template you do this with the {% url %} templatetag, in code you use django.core.urlresolvers.reverse().

Django: How do I pass a form's input content from within a same page?

I have just started on Django and am quite new to the whole thing.
I went through the whole tutorial on
https://docs.djangoproject.com/en/1.7/intro/tutorial03/ , which involves settings up the database and writing a simple form.
To start off my journey in Django, I plan to write a simple app that runs on localhost. And I have faced a issue in passing inputs form a form.
I have created a Name class in the models.py with 1 attribute
#name of the person
value = models.CharField(max_length=50)
In my index link: http://localhost:8000/helloworld/, it contains a simple 1-input-field form as follows:
<form method="post" action="{% url 'helloworld:hello' %}">
{% csrf_token %}
Enter Name: <input size="80" name="link" type="text">
<button type="submit">Submit</button>
</form>
The aim of the form is to return the input data to the same link (http://localhost:8000/helloworld/) with a input message of:
"Welcome [NAME], Hello World"
In my views.py, the following method is written:
def hello(request,name):
p = get_object_or_404(Link, pk=name)
try:
input_link = p.choice_set.get(pk=request.POST['link'])
except (KeyError, Link.DoesNotExist):
return render(request, 'helloworld/index.html',{
'error_message': "You did not enter a name",
})
else:
return HttpResponseRedirect(reverse('helloworld:index', args=(p.value)))
How ever if I access the page http://localhost:8000/helloworld/, and entered a data in the field and click submit, it brings me to the page
Page not found (404)
Request Method: POST
Request URL: http://localhost:8000/helloworld/url%20'helloworld:hello'
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^helloworld/ ^$ [name='index']
^helloworld/ ^(?P<pk>\d+)/$ [name='detail']
^helloworld/ ^(?P<pk>\d+)/results/$ [name='results']
^helloworld/ ^(?P<question_id>\d+)/vote/$ [name='vote']
^admin/
The current URL, helloworld/url 'helloworld:hello', didn't match any of these.
The content in the urls.py was from https://docs.djangoproject.com/en/1.7/intro/tutorial04/#amend-urlconf
As requested, the content of urls.py:
from django.conf.urls import patterns, url
from domparser import views
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
)
May I know how do I go about solving this issue?
Thanks!
Simply an answer for this type. If you want to post to same url you are currently now.Try this and chenge def hello(request, name) to def hello(request).
action=""
Otherwise if urls.py
urlpatterns = patterns('app.views',
url(r'^$', view="index", name="app_index"),
)
Try this
action="{% url app_index %}"
As i found, in yours you can apply
action="{% url helloworld:index %}"
Hope this helps
For your answer updated. Try this
<form method="post" action="{% url "index" %}">
You need change this line
<form method="post" action="{% url 'helloworld:hello' %}">
to
<form method="post" action="{% 'helloworld:hello' %}">

Categories

Resources